blob: 72928472211a95171d313a697524c508831e527d [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
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700889int decode_poll_for_platform_event_message_req(
890 const struct pldm_msg *msg, size_t payload_length, uint8_t *format_version,
891 uint8_t *transfer_operation_flag, uint32_t *data_transfer_handle,
892 uint16_t *event_id_to_acknowledge)
893{
894 struct pldm_msgbuf _buf;
895 struct pldm_msgbuf *buf = &_buf;
896 int rc;
897
898 if (msg == NULL) {
899 return PLDM_ERROR_INVALID_DATA;
900 }
901
902 rc = pldm_msgbuf_init(buf,
903 PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
904 msg->payload, payload_length);
905 if (rc) {
906 return rc;
907 }
908
909 pldm_msgbuf_extract(buf, format_version);
910 rc = pldm_msgbuf_extract(buf, transfer_operation_flag);
911 if (rc) {
912 return rc;
913 }
914 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
915 return PLDM_ERROR_INVALID_DATA;
916 }
917
918 pldm_msgbuf_extract(buf, data_transfer_handle);
919 rc = pldm_msgbuf_extract(buf, event_id_to_acknowledge);
920 if (rc) {
921 return rc;
922 }
923
924 if (!(((*transfer_operation_flag == PLDM_GET_NEXTPART) &&
925 (*event_id_to_acknowledge == 0xFFFF)) ||
926 ((*transfer_operation_flag == PLDM_GET_FIRSTPART) &&
927 (*event_id_to_acknowledge == 0x000)) ||
928 (*transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY))) {
929 return PLDM_ERROR_INVALID_DATA;
930 }
931
932 return pldm_msgbuf_destroy(buf);
933}
934
Andrew Jeffery9c766792022-08-10 23:12:49 +0930935int encode_platform_event_message_resp(uint8_t instance_id,
936 uint8_t completion_code,
937 uint8_t platform_event_status,
938 struct pldm_msg *msg)
939{
940 if (msg == NULL) {
941 return PLDM_ERROR_INVALID_DATA;
942 }
943
944 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
945 return PLDM_ERROR_INVALID_DATA;
946 }
947
948 struct pldm_header_info header = {0};
949 header.msg_type = PLDM_RESPONSE;
950 header.instance = instance_id;
951 header.pldm_type = PLDM_PLATFORM;
952 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
953
954 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
955 if (rc != PLDM_SUCCESS) {
956 return rc;
957 }
958
959 struct pldm_platform_event_message_resp *response =
960 (struct pldm_platform_event_message_resp *)msg->payload;
961 response->completion_code = completion_code;
962 response->platform_event_status = platform_event_status;
963
964 return PLDM_SUCCESS;
965}
966
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700967int encode_poll_for_platform_event_message_resp(
968 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
969 uint16_t event_id, uint32_t next_data_transfer_handle,
970 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
971 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
972 size_t payload_length)
973{
974 struct pldm_msgbuf _buf;
975 struct pldm_msgbuf *buf = &_buf;
976 int rc;
977
978 if (!msg) {
979 return PLDM_ERROR_INVALID_DATA;
980 }
981
982 struct pldm_header_info header = {0};
983 header.msg_type = PLDM_RESPONSE;
984 header.instance = instance_id;
985 header.pldm_type = PLDM_PLATFORM;
986 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
987
988 rc = pack_pldm_header(&header, &(msg->hdr));
989 if (rc != PLDM_SUCCESS) {
990 return rc;
991 }
992
993 rc = pldm_msgbuf_init(
994 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
995 msg->payload, payload_length);
996 if (rc) {
997 return rc;
998 }
999
1000 pldm_msgbuf_insert(buf, completion_code);
1001 pldm_msgbuf_insert(buf, tid);
1002 pldm_msgbuf_insert(buf, event_id);
1003
1004 if (event_id == 0xffff || event_id == 0x0000) {
1005 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1006 payload_length) {
1007 return PLDM_ERROR_INVALID_LENGTH;
1008 }
1009 return pldm_msgbuf_destroy(buf);
1010 }
1011
1012 if ((event_data == NULL) && (event_data_size > 0)) {
1013 return PLDM_ERROR_INVALID_DATA;
1014 }
1015
1016 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1017 pldm_msgbuf_insert(buf, transfer_flag);
1018 pldm_msgbuf_insert(buf, event_class);
1019 pldm_msgbuf_insert(buf, event_data_size);
1020
1021 if ((event_data_size > 0) && event_data) {
1022 pldm_msgbuf_insert_array(buf, event_data, event_data_size);
1023 }
1024
1025 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1026 pldm_msgbuf_insert(buf, checksum);
1027 }
1028
1029 return pldm_msgbuf_destroy(buf);
1030}
1031
Andrew Jeffery9c766792022-08-10 23:12:49 +09301032int encode_platform_event_message_req(
1033 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1034 uint8_t event_class, const uint8_t *event_data, size_t event_data_length,
1035 struct pldm_msg *msg, size_t payload_length)
1036
1037{
1038 if (format_version != 1) {
1039 return PLDM_ERROR_INVALID_DATA;
1040 }
1041
1042 if (msg == NULL || event_data == NULL) {
1043 return PLDM_ERROR_INVALID_DATA;
1044 }
1045
1046 if (event_data_length == 0) {
1047 return PLDM_ERROR_INVALID_DATA;
1048 }
1049
1050 if (payload_length !=
1051 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1052 return PLDM_ERROR_INVALID_LENGTH;
1053 }
1054
1055 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
1056 !(event_class >= 0xF0 && event_class <= 0xFE)) {
1057 return PLDM_ERROR_INVALID_DATA;
1058 }
1059
1060 struct pldm_header_info header = {0};
1061 header.msg_type = PLDM_REQUEST;
1062 header.instance = instance_id;
1063 header.pldm_type = PLDM_PLATFORM;
1064 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1065
1066 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1067 if (rc != PLDM_SUCCESS) {
1068 return rc;
1069 }
1070
1071 struct pldm_platform_event_message_req *request =
1072 (struct pldm_platform_event_message_req *)msg->payload;
1073 request->format_version = format_version;
1074 request->tid = tid;
1075 request->event_class = event_class;
1076 memcpy(request->event_data, event_data, event_data_length);
1077
1078 return PLDM_SUCCESS;
1079}
1080
1081int decode_platform_event_message_resp(const struct pldm_msg *msg,
1082 size_t payload_length,
1083 uint8_t *completion_code,
1084 uint8_t *platform_event_status)
1085{
Andrew Jefferye5011772023-04-13 12:06:22 +09301086 struct pldm_msgbuf _buf;
1087 struct pldm_msgbuf *buf = &_buf;
1088 int rc;
1089
Andrew Jeffery9c766792022-08-10 23:12:49 +09301090 if (msg == NULL || completion_code == NULL ||
1091 platform_event_status == NULL) {
1092 return PLDM_ERROR_INVALID_DATA;
1093 }
1094
Andrew Jefferye5011772023-04-13 12:06:22 +09301095 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1096 msg->payload, payload_length);
1097 if (rc) {
1098 return rc;
1099 }
1100
1101 rc = pldm_msgbuf_extract(buf, completion_code);
1102 if (rc) {
1103 return rc;
1104 }
1105
Andrew Jeffery9c766792022-08-10 23:12:49 +09301106 if (PLDM_SUCCESS != *completion_code) {
1107 return PLDM_SUCCESS;
1108 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301109
Andrew Jefferye5011772023-04-13 12:06:22 +09301110 rc = pldm_msgbuf_extract(buf, platform_event_status);
1111 if (rc) {
1112 return rc;
1113 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301114
1115 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1116 return PLDM_ERROR_INVALID_DATA;
1117 }
1118
Andrew Jefferye5011772023-04-13 12:06:22 +09301119 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301120}
1121
Dung Caod6ae8982022-11-02 10:00:10 +07001122int encode_event_message_buffer_size_req(
1123 uint8_t instance_id, uint16_t event_receiver_max_buffer_size,
1124 struct pldm_msg *msg)
1125{
1126 struct pldm_header_info header = {0};
1127 header.msg_type = PLDM_REQUEST;
1128 header.instance = instance_id;
1129 header.pldm_type = PLDM_PLATFORM;
1130 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1131
1132 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1133 if (rc != PLDM_SUCCESS) {
1134 return rc;
1135 }
1136
1137 struct pldm_event_message_buffer_size_req *request =
1138 (struct pldm_event_message_buffer_size_req *)msg->payload;
1139 request->event_receiver_max_buffer_size =
1140 event_receiver_max_buffer_size;
1141
1142 return PLDM_SUCCESS;
1143}
1144
1145int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1146 size_t payload_length,
1147 uint8_t *completion_code,
1148 uint16_t *terminus_max_buffer_size)
1149{
Andrew Jeffery11126902023-04-13 12:12:10 +09301150 struct pldm_msgbuf _buf;
1151 struct pldm_msgbuf *buf = &_buf;
1152 int rc;
1153
Dung Caod6ae8982022-11-02 10:00:10 +07001154 if (msg == NULL || completion_code == NULL ||
1155 terminus_max_buffer_size == NULL) {
1156 return PLDM_ERROR_INVALID_DATA;
1157 }
1158
Andrew Jeffery11126902023-04-13 12:12:10 +09301159 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1160 msg->payload, payload_length);
1161 if (rc) {
1162 return rc;
1163 }
1164
1165 rc = pldm_msgbuf_extract(buf, completion_code);
1166 if (rc) {
1167 return rc;
1168 }
1169
Dung Caod6ae8982022-11-02 10:00:10 +07001170 if (PLDM_SUCCESS != *completion_code) {
1171 return PLDM_SUCCESS;
1172 }
Dung Caod6ae8982022-11-02 10:00:10 +07001173
Andrew Jeffery11126902023-04-13 12:12:10 +09301174 pldm_msgbuf_extract(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001175
Andrew Jeffery11126902023-04-13 12:12:10 +09301176 return pldm_msgbuf_destroy_consumed(buf);
Dung Caod6ae8982022-11-02 10:00:10 +07001177}
1178
Dung Cao1bf8c872022-11-29 05:32:58 +07001179int encode_event_message_supported_req(uint8_t instance_id,
1180 uint8_t format_version,
1181 struct pldm_msg *msg)
1182{
1183 if (format_version != 1) {
1184 return PLDM_ERROR_INVALID_DATA;
1185 }
1186
1187 if (msg == NULL) {
1188 return PLDM_ERROR_INVALID_DATA;
1189 }
1190
1191 struct pldm_header_info header = {0};
1192 header.msg_type = PLDM_REQUEST;
1193 header.instance = instance_id;
1194 header.pldm_type = PLDM_PLATFORM;
1195 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1196
1197 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1198 if (rc != PLDM_SUCCESS) {
1199 return rc;
1200 }
1201
1202 struct pldm_event_message_supported_req *request =
1203 (struct pldm_event_message_supported_req *)msg->payload;
1204 request->format_version = format_version;
1205
1206 return PLDM_SUCCESS;
1207}
1208
1209int decode_event_message_supported_resp(
1210 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1211 uint8_t *synchrony_config, bitfield8_t *synchrony_config_support,
1212 uint8_t *number_event_class_returned, uint8_t *event_class,
1213 uint8_t event_class_count)
1214{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301215 struct pldm_msgbuf _buf;
1216 struct pldm_msgbuf *buf = &_buf;
1217 int i;
1218 int rc;
1219
Dung Cao1bf8c872022-11-29 05:32:58 +07001220 if (msg == NULL || completion_code == NULL ||
1221 synchrony_config == NULL || synchrony_config_support == NULL ||
1222 number_event_class_returned == NULL || event_class == NULL) {
1223 return PLDM_ERROR_INVALID_DATA;
1224 }
1225
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301226 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1227 msg->payload, payload_length);
1228 if (rc) {
1229 return rc;
1230 }
1231
1232 rc = pldm_msgbuf_extract(buf, completion_code);
1233 if (rc) {
1234 return rc;
1235 }
1236
Dung Cao1bf8c872022-11-29 05:32:58 +07001237 if (PLDM_SUCCESS != *completion_code) {
1238 return PLDM_SUCCESS;
1239 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301240
1241 rc = pldm_msgbuf_extract(buf, synchrony_config);
1242 if (rc) {
1243 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001244 }
1245
Dung Cao1bf8c872022-11-29 05:32:58 +07001246 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1247 return PLDM_ERROR_INVALID_DATA;
1248 }
1249
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301250 pldm_msgbuf_extract(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001251
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301252 rc = pldm_msgbuf_extract(buf, number_event_class_returned);
1253 if (rc) {
1254 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001255 }
1256
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301257 if (*number_event_class_returned == 0) {
1258 return pldm_msgbuf_destroy(buf);
1259 }
1260
1261 if (event_class_count < *number_event_class_returned) {
1262 return PLDM_ERROR_INVALID_LENGTH;
1263 }
1264
1265 for (i = 0; i < *number_event_class_returned; i++) {
1266 pldm_msgbuf_extract(buf, &event_class[i]);
1267 }
1268
1269 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao1bf8c872022-11-29 05:32:58 +07001270}
1271
Andrew Jeffery9c766792022-08-10 23:12:49 +09301272int decode_sensor_event_data(const uint8_t *event_data,
1273 size_t event_data_length, uint16_t *sensor_id,
1274 uint8_t *sensor_event_class_type,
1275 size_t *event_class_data_offset)
1276{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301277 struct pldm_msgbuf _buf;
1278 struct pldm_msgbuf *buf = &_buf;
1279 int rc;
1280
1281 rc = pldm_msgbuf_init(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1282 event_data, event_data_length);
1283 if (rc) {
1284 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301285 }
1286
1287 size_t event_class_data_length =
1288 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
1289
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301290 pldm_msgbuf_extract(buf, sensor_id);
1291 rc = pldm_msgbuf_extract(buf, sensor_event_class_type);
1292 if (rc) {
1293 return rc;
1294 }
1295
1296 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301297 if (event_class_data_length !=
1298 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1299 return PLDM_ERROR_INVALID_LENGTH;
1300 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301301 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301302 if (event_class_data_length !=
1303 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1304 return PLDM_ERROR_INVALID_LENGTH;
1305 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301306 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301307 if (event_class_data_length <
1308 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
1309 event_class_data_length >
1310 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1311 return PLDM_ERROR_INVALID_LENGTH;
1312 }
1313 } else {
1314 return PLDM_ERROR_INVALID_DATA;
1315 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301316
Andrew Jeffery9c766792022-08-10 23:12:49 +09301317 *event_class_data_offset =
1318 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301319
1320 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301321}
1322
1323int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1324 uint8_t *present_op_state, uint8_t *previous_op_state)
1325{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301326 struct pldm_msgbuf _buf;
1327 struct pldm_msgbuf *buf = &_buf;
1328 int rc;
1329
1330 if (present_op_state == NULL || previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301331 return PLDM_ERROR_INVALID_DATA;
1332 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301333
1334 rc =
1335 pldm_msgbuf_init(buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH,
1336 sensor_data, sensor_data_length);
1337 if (rc) {
1338 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301339 }
1340
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301341 pldm_msgbuf_extract(buf, present_op_state);
1342 pldm_msgbuf_extract(buf, previous_op_state);
1343
1344 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301345}
1346
1347int decode_state_sensor_data(const uint8_t *sensor_data,
1348 size_t sensor_data_length, uint8_t *sensor_offset,
1349 uint8_t *event_state,
1350 uint8_t *previous_event_state)
1351{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301352 struct pldm_msgbuf _buf;
1353 struct pldm_msgbuf *buf = &_buf;
1354 int rc;
1355
1356 if (sensor_offset == NULL || event_state == NULL ||
1357 previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301358 return PLDM_ERROR_INVALID_DATA;
1359 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301360
1361 rc = pldm_msgbuf_init(buf,
1362 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1363 sensor_data, sensor_data_length);
1364 if (rc) {
1365 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301366 }
1367
Andrew Jeffery422790b2023-04-13 15:03:47 +09301368 pldm_msgbuf_extract(buf, sensor_offset);
1369 pldm_msgbuf_extract(buf, event_state);
1370 pldm_msgbuf_extract(buf, previous_event_state);
1371
1372 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301373}
1374
1375int decode_numeric_sensor_data(const uint8_t *sensor_data,
1376 size_t sensor_data_length, uint8_t *event_state,
1377 uint8_t *previous_event_state,
1378 uint8_t *sensor_data_size,
1379 uint32_t *present_reading)
1380{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301381 struct pldm_msgbuf _buf;
1382 struct pldm_msgbuf *buf = &_buf;
1383 int rc;
1384
1385 if (sensor_data_size == NULL || event_state == NULL ||
1386 previous_event_state == NULL || present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301387 return PLDM_ERROR_INVALID_DATA;
1388 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301389
1390 if (sensor_data_length >
1391 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301392 return PLDM_ERROR_INVALID_LENGTH;
1393 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301394
Andrew Jeffery155317e2023-04-13 18:36:51 +09301395 rc = pldm_msgbuf_init(
1396 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1397 sensor_data, sensor_data_length);
1398 if (rc) {
1399 return rc;
1400 }
1401
1402 pldm_msgbuf_extract(buf, event_state);
1403 pldm_msgbuf_extract(buf, previous_event_state);
1404 rc = pldm_msgbuf_extract(buf, sensor_data_size);
1405 if (rc) {
1406 return rc;
1407 }
1408
1409 /*
1410 * The implementation below is bonkers, but it's because the function
1411 * prototype is bonkers. The `present_reading` argument should have been
1412 * a tagged union.
1413 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301414 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301415 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1416 uint8_t val;
1417 if (!pldm_msgbuf_extract(buf, &val)) {
1418 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301419 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301420 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301421 }
1422 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1423 int8_t val;
1424 if (!pldm_msgbuf_extract(buf, &val)) {
1425 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301426 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301427 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301428 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301429 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301430 uint16_t val;
1431 if (!pldm_msgbuf_extract(buf, &val)) {
1432 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301433 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301434 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301435 }
1436 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301437 int16_t val;
1438 if (!pldm_msgbuf_extract(buf, &val)) {
1439 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301440 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301441 break;
1442 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301443 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1444 uint32_t val;
1445 if (!pldm_msgbuf_extract(buf, &val)) {
1446 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301447 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301448 break;
1449 }
1450 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1451 int32_t val;
1452 if (!pldm_msgbuf_extract(buf, &val)) {
1453 *present_reading = (uint32_t)val;
1454 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301455 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301456 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301457 default:
1458 return PLDM_ERROR_INVALID_DATA;
1459 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301460
1461 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301462}
1463
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301464#define PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE 69
1465int decode_numeric_sensor_pdr_data(
1466 const void *pdr_data, size_t pdr_data_length,
1467 struct pldm_numeric_sensor_value_pdr *pdr_value)
1468{
1469 struct pldm_msgbuf _buf;
1470 struct pldm_msgbuf *buf = &_buf;
1471 int rc;
1472
1473 rc = pldm_msgbuf_init(buf, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1474 pdr_data, pdr_data_length);
1475 if (rc) {
1476 return rc;
1477 }
1478
1479 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1480 if (rc) {
1481 return rc;
1482 }
1483
1484 rc = pldm_platform_pdr_hdr_validate(
1485 &pdr_value->hdr, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1486 pdr_data_length);
1487 if (rc) {
1488 return rc;
1489 }
1490
1491 pldm_msgbuf_extract(buf, &pdr_value->terminus_handle);
1492 pldm_msgbuf_extract(buf, &pdr_value->sensor_id);
1493 pldm_msgbuf_extract(buf, &pdr_value->entity_type);
1494 pldm_msgbuf_extract(buf, &pdr_value->entity_instance_num);
1495 pldm_msgbuf_extract(buf, &pdr_value->container_id);
1496 pldm_msgbuf_extract(buf, &pdr_value->sensor_init);
1497 pldm_msgbuf_extract(buf, &pdr_value->sensor_auxiliary_names_pdr);
1498 pldm_msgbuf_extract(buf, &pdr_value->base_unit);
1499 pldm_msgbuf_extract(buf, &pdr_value->unit_modifier);
1500 pldm_msgbuf_extract(buf, &pdr_value->rate_unit);
1501 pldm_msgbuf_extract(buf, &pdr_value->base_oem_unit_handle);
1502 pldm_msgbuf_extract(buf, &pdr_value->aux_unit);
1503 pldm_msgbuf_extract(buf, &pdr_value->aux_unit_modifier);
1504 pldm_msgbuf_extract(buf, &pdr_value->aux_rate_unit);
1505 pldm_msgbuf_extract(buf, &pdr_value->rel);
1506 pldm_msgbuf_extract(buf, &pdr_value->aux_oem_unit_handle);
1507 pldm_msgbuf_extract(buf, &pdr_value->is_linear);
1508
1509 rc = pldm_msgbuf_extract(buf, &pdr_value->sensor_data_size);
1510 if (rc) {
1511 return rc;
1512 }
1513 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1514 return PLDM_ERROR_INVALID_DATA;
1515 }
1516
1517 pldm_msgbuf_extract(buf, &pdr_value->resolution);
1518 pldm_msgbuf_extract(buf, &pdr_value->offset);
1519 pldm_msgbuf_extract(buf, &pdr_value->accuracy);
1520 pldm_msgbuf_extract(buf, &pdr_value->plus_tolerance);
1521 pldm_msgbuf_extract(buf, &pdr_value->minus_tolerance);
1522 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1523 &pdr_value->hysteresis);
1524 pldm_msgbuf_extract(buf, &pdr_value->supported_thresholds.byte);
1525 pldm_msgbuf_extract(
1526 buf, &pdr_value->threshold_and_hysteresis_volatility.byte);
1527 pldm_msgbuf_extract(buf, &pdr_value->state_transition_interval);
1528 pldm_msgbuf_extract(buf, &pdr_value->update_interval);
1529 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1530 &pdr_value->max_readable);
1531 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1532 &pdr_value->min_readable);
1533
1534 rc = pldm_msgbuf_extract(buf, &pdr_value->range_field_format);
1535 if (rc) {
1536 return rc;
1537 }
1538 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1539 return PLDM_ERROR_INVALID_DATA;
1540 }
1541
1542 pldm_msgbuf_extract(buf, &pdr_value->range_field_support.byte);
1543 pldm_msgbuf_extract_range_field_format(
1544 buf, pdr_value->range_field_format, &pdr_value->nominal_value);
1545 pldm_msgbuf_extract_range_field_format(
1546 buf, pdr_value->range_field_format, &pdr_value->normal_max);
1547 pldm_msgbuf_extract_range_field_format(
1548 buf, pdr_value->range_field_format, &pdr_value->normal_min);
1549 pldm_msgbuf_extract_range_field_format(
1550 buf, pdr_value->range_field_format, &pdr_value->warning_high);
1551 pldm_msgbuf_extract_range_field_format(
1552 buf, pdr_value->range_field_format, &pdr_value->warning_low);
1553 pldm_msgbuf_extract_range_field_format(
1554 buf, pdr_value->range_field_format, &pdr_value->critical_high);
1555 pldm_msgbuf_extract_range_field_format(
1556 buf, pdr_value->range_field_format, &pdr_value->critical_low);
1557 pldm_msgbuf_extract_range_field_format(
1558 buf, pdr_value->range_field_format, &pdr_value->fatal_high);
1559 pldm_msgbuf_extract_range_field_format(
1560 buf, pdr_value->range_field_format, &pdr_value->fatal_low);
1561
1562 return pldm_msgbuf_destroy(buf);
1563}
1564
Andrew Jeffery9c766792022-08-10 23:12:49 +09301565int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1566 uint16_t effecter_id,
1567 struct pldm_msg *msg)
1568{
1569 if (msg == NULL) {
1570 return PLDM_ERROR_INVALID_DATA;
1571 }
1572
1573 struct pldm_header_info header = {0};
1574 header.msg_type = PLDM_REQUEST;
1575 header.instance = instance_id;
1576 header.pldm_type = PLDM_PLATFORM;
1577 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1578
1579 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1580 if (rc != PLDM_SUCCESS) {
1581 return rc;
1582 }
1583
1584 struct pldm_get_numeric_effecter_value_req *request =
1585 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1586 request->effecter_id = htole16(effecter_id);
1587
1588 return PLDM_SUCCESS;
1589}
1590
1591int encode_get_numeric_effecter_value_resp(
1592 uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
Andrew Jefferydebe6b32023-04-05 20:30:46 +09301593 uint8_t effecter_oper_state, const uint8_t *pending_value,
1594 const uint8_t *present_value, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301595{
1596 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1597 return PLDM_ERROR_INVALID_DATA;
1598 }
1599
1600 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1601 return PLDM_ERROR_INVALID_DATA;
1602 }
1603
1604 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1605 return PLDM_ERROR_INVALID_DATA;
1606 }
1607
1608 struct pldm_header_info header = {0};
1609 header.msg_type = PLDM_RESPONSE;
1610 header.instance = instance_id;
1611 header.pldm_type = PLDM_PLATFORM;
1612 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1613
1614 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1615 if (rc != PLDM_SUCCESS) {
1616 return rc;
1617 }
1618
1619 struct pldm_get_numeric_effecter_value_resp *response =
1620 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1621
1622 response->completion_code = completion_code;
1623 response->effecter_data_size = effecter_data_size;
1624 response->effecter_oper_state = effecter_oper_state;
1625
1626 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1627 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1628 if (payload_length !=
1629 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1630 return PLDM_ERROR_INVALID_LENGTH;
1631 }
1632 response->pending_and_present_values[0] = *pending_value;
1633 response->pending_and_present_values[1] = *present_value;
1634
1635 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1636 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1637 if (payload_length !=
1638 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1639 return PLDM_ERROR_INVALID_LENGTH;
1640 }
1641 uint16_t val_pending = *(uint16_t *)pending_value;
1642 val_pending = htole16(val_pending);
1643 memcpy(response->pending_and_present_values, &val_pending,
1644 sizeof(uint16_t));
1645 uint16_t val_present = *(uint16_t *)present_value;
1646 val_present = htole16(val_present);
1647 memcpy(
1648 (response->pending_and_present_values + sizeof(uint16_t)),
1649 &val_present, sizeof(uint16_t));
1650
1651 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1652 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1653 if (payload_length !=
1654 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1655 return PLDM_ERROR_INVALID_LENGTH;
1656 }
1657 uint32_t val_pending = *(uint32_t *)pending_value;
1658 val_pending = htole32(val_pending);
1659 memcpy(response->pending_and_present_values, &val_pending,
1660 sizeof(uint32_t));
1661 uint32_t val_present = *(uint32_t *)present_value;
1662 val_present = htole32(val_present);
1663 memcpy(
1664 (response->pending_and_present_values + sizeof(uint32_t)),
1665 &val_present, sizeof(uint32_t));
1666 }
1667 return PLDM_SUCCESS;
1668}
1669
1670int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1671 size_t payload_length,
1672 uint16_t *effecter_id)
1673{
Andrew Jefferydd265822023-04-13 22:42:44 +09301674 struct pldm_msgbuf _buf;
1675 struct pldm_msgbuf *buf = &_buf;
1676 int rc;
1677
Andrew Jeffery9c766792022-08-10 23:12:49 +09301678 if (msg == NULL || effecter_id == NULL) {
1679 return PLDM_ERROR_INVALID_DATA;
1680 }
1681
Andrew Jefferydd265822023-04-13 22:42:44 +09301682 rc = pldm_msgbuf_init(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
1683 msg->payload, payload_length);
1684 if (rc) {
1685 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301686 }
1687
Andrew Jefferydd265822023-04-13 22:42:44 +09301688 pldm_msgbuf_extract(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301689
Andrew Jefferydd265822023-04-13 22:42:44 +09301690 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301691}
1692
1693int decode_get_numeric_effecter_value_resp(
1694 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1695 uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
1696 uint8_t *pending_value, uint8_t *present_value)
1697{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301698 struct pldm_msgbuf _buf;
1699 struct pldm_msgbuf *buf = &_buf;
1700 int rc;
1701
Andrew Jeffery9c766792022-08-10 23:12:49 +09301702 if (msg == NULL || effecter_data_size == NULL ||
1703 effecter_oper_state == NULL || pending_value == NULL ||
1704 present_value == NULL) {
1705 return PLDM_ERROR_INVALID_DATA;
1706 }
1707
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301708 rc = pldm_msgbuf_init(buf,
1709 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
1710 msg->payload, payload_length);
1711 if (rc) {
1712 return rc;
1713 }
1714
1715 rc = pldm_msgbuf_extract(buf, completion_code);
1716 if (rc) {
1717 return rc;
1718 }
1719
Andrew Jeffery9c766792022-08-10 23:12:49 +09301720 if (PLDM_SUCCESS != *completion_code) {
1721 return PLDM_SUCCESS;
1722 }
1723
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301724 rc = pldm_msgbuf_extract(buf, effecter_data_size);
1725 if (rc) {
1726 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301727 }
1728
Andrew Jeffery9c766792022-08-10 23:12:49 +09301729 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1730 return PLDM_ERROR_INVALID_DATA;
1731 }
1732
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301733 rc = pldm_msgbuf_extract(buf, effecter_oper_state);
1734 if (rc) {
1735 return rc;
1736 }
1737
Andrew Jeffery9c766792022-08-10 23:12:49 +09301738 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1739 return PLDM_ERROR_INVALID_DATA;
1740 }
1741
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301742 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1743 pending_value);
1744 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1745 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301746
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301747 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301748}
1749
1750int encode_pldm_pdr_repository_chg_event_data(
1751 uint8_t event_data_format, uint8_t number_of_change_records,
1752 const uint8_t *event_data_operations,
1753 const uint8_t *numbers_of_change_entries,
1754 const uint32_t *const *change_entries,
1755 struct pldm_pdr_repository_chg_event_data *event_data,
1756 size_t *actual_change_records_size, size_t max_change_records_size)
1757{
1758 if (event_data_operations == NULL ||
1759 numbers_of_change_entries == NULL || change_entries == NULL) {
1760 return PLDM_ERROR_INVALID_DATA;
1761 }
1762
1763 size_t expected_size =
1764 sizeof(event_data_format) + sizeof(number_of_change_records);
1765
1766 expected_size +=
1767 sizeof(*event_data_operations) * number_of_change_records;
1768 expected_size +=
1769 sizeof(*numbers_of_change_entries) * number_of_change_records;
1770
1771 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1772 expected_size +=
1773 sizeof(*change_entries[0]) * numbers_of_change_entries[i];
1774 }
1775
1776 *actual_change_records_size = expected_size;
1777
1778 if (event_data == NULL) {
1779 return PLDM_SUCCESS;
1780 }
1781
1782 if (max_change_records_size < expected_size) {
1783 return PLDM_ERROR_INVALID_LENGTH;
1784 }
1785
1786 event_data->event_data_format = event_data_format;
1787 event_data->number_of_change_records = number_of_change_records;
1788
1789 struct pldm_pdr_repository_change_record_data *record_data =
1790 (struct pldm_pdr_repository_change_record_data *)
1791 event_data->change_records;
1792
1793 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1794 record_data->event_data_operation = event_data_operations[i];
1795 record_data->number_of_change_entries =
1796 numbers_of_change_entries[i];
1797
1798 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1799 ++j) {
1800 record_data->change_entry[j] =
1801 htole32(change_entries[i][j]);
1802 }
1803
1804 record_data = (struct pldm_pdr_repository_change_record_data
1805 *)(record_data->change_entry +
1806 record_data->number_of_change_entries);
1807 }
1808
1809 return PLDM_SUCCESS;
1810}
1811
1812int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1813 size_t event_data_size,
1814 uint8_t *event_data_format,
1815 uint8_t *number_of_change_records,
1816 size_t *change_record_data_offset)
1817{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301818 struct pldm_msgbuf _buf;
1819 struct pldm_msgbuf *buf = &_buf;
1820 int rc;
1821
1822 if (event_data_format == NULL || number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301823 change_record_data_offset == NULL) {
1824 return PLDM_ERROR_INVALID_DATA;
1825 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301826
1827 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
1828 event_data, event_data_size);
1829 if (rc) {
1830 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301831 }
1832
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301833 pldm_msgbuf_extract(buf, event_data_format);
1834 pldm_msgbuf_extract(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301835
Andrew Jeffery9c766792022-08-10 23:12:49 +09301836 *change_record_data_offset =
1837 sizeof(*event_data_format) + sizeof(*number_of_change_records);
1838
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301839 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301840}
1841
1842int decode_pldm_pdr_repository_change_record_data(
1843 const uint8_t *change_record_data, size_t change_record_data_size,
1844 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1845 size_t *change_entry_data_offset)
1846{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301847 struct pldm_msgbuf _buf;
1848 struct pldm_msgbuf *buf = &_buf;
1849 int rc;
1850
1851 if (event_data_operation == NULL || number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301852 change_entry_data_offset == NULL) {
1853 return PLDM_ERROR_INVALID_DATA;
1854 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301855
1856 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
1857 change_record_data, change_record_data_size);
1858 if (rc) {
1859 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301860 }
1861
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301862 pldm_msgbuf_extract(buf, event_data_operation);
1863 pldm_msgbuf_extract(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301864
Andrew Jeffery9c766792022-08-10 23:12:49 +09301865 *change_entry_data_offset =
1866 sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
1867
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301868 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301869}
1870
1871int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1872 uint8_t rearm_event_state,
1873 struct pldm_msg *msg)
1874{
1875 if (msg == NULL) {
1876 return PLDM_ERROR_INVALID_DATA;
1877 }
1878
1879 struct pldm_header_info header = {0};
1880 header.msg_type = PLDM_REQUEST;
1881 header.instance = instance_id;
1882 header.pldm_type = PLDM_PLATFORM;
1883 header.command = PLDM_GET_SENSOR_READING;
1884
1885 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1886 if (rc != PLDM_SUCCESS) {
1887 return rc;
1888 }
1889
1890 struct pldm_get_sensor_reading_req *request =
1891 (struct pldm_get_sensor_reading_req *)msg->payload;
1892
1893 request->sensor_id = htole16(sensor_id);
1894 request->rearm_event_state = rearm_event_state;
1895
1896 return PLDM_SUCCESS;
1897}
1898
1899int decode_get_sensor_reading_resp(
1900 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1901 uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
1902 uint8_t *sensor_event_message_enable, uint8_t *present_state,
1903 uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
1904{
Andrew Jeffery840b1402023-04-13 23:54:44 +09301905 struct pldm_msgbuf _buf;
1906 struct pldm_msgbuf *buf = &_buf;
1907 int rc;
1908
Andrew Jeffery9c766792022-08-10 23:12:49 +09301909 if (msg == NULL || completion_code == NULL ||
1910 sensor_data_size == NULL || sensor_operational_state == NULL ||
1911 sensor_event_message_enable == NULL || present_state == NULL ||
1912 previous_state == NULL || event_state == NULL ||
1913 present_reading == NULL) {
1914 return PLDM_ERROR_INVALID_DATA;
1915 }
1916
Andrew Jeffery840b1402023-04-13 23:54:44 +09301917 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
1918 msg->payload, payload_length);
1919 if (rc) {
1920 return rc;
1921 }
1922
1923 rc = pldm_msgbuf_extract(buf, completion_code);
1924 if (rc) {
1925 return rc;
1926 }
1927
Andrew Jeffery9c766792022-08-10 23:12:49 +09301928 if (PLDM_SUCCESS != *completion_code) {
1929 return PLDM_SUCCESS;
1930 }
1931
Andrew Jeffery840b1402023-04-13 23:54:44 +09301932 rc = pldm_msgbuf_extract(buf, sensor_data_size);
1933 if (rc) {
1934 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301935 }
1936
Andrew Jeffery840b1402023-04-13 23:54:44 +09301937 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301938 return PLDM_ERROR_INVALID_DATA;
1939 }
1940
Andrew Jeffery840b1402023-04-13 23:54:44 +09301941 pldm_msgbuf_extract(buf, sensor_operational_state);
1942 pldm_msgbuf_extract(buf, sensor_event_message_enable);
1943 pldm_msgbuf_extract(buf, present_state);
1944 pldm_msgbuf_extract(buf, previous_state);
1945 pldm_msgbuf_extract(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301946
Andrew Jeffery840b1402023-04-13 23:54:44 +09301947 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
1948 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301949
Andrew Jeffery840b1402023-04-13 23:54:44 +09301950 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301951}
1952
1953int encode_get_sensor_reading_resp(
1954 uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
1955 uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
1956 uint8_t present_state, uint8_t previous_state, uint8_t event_state,
Andrew Jefferydebe6b32023-04-05 20:30:46 +09301957 const uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301958{
1959 if (msg == NULL || present_reading == NULL) {
1960 return PLDM_ERROR_INVALID_DATA;
1961 }
1962
1963 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1964 return PLDM_ERROR_INVALID_DATA;
1965 }
1966
1967 struct pldm_header_info header = {0};
1968 header.msg_type = PLDM_RESPONSE;
1969 header.instance = instance_id;
1970 header.pldm_type = PLDM_PLATFORM;
1971 header.command = PLDM_GET_SENSOR_READING;
1972
1973 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1974 if (rc != PLDM_SUCCESS) {
1975 return rc;
1976 }
1977
1978 struct pldm_get_sensor_reading_resp *response =
1979 (struct pldm_get_sensor_reading_resp *)msg->payload;
1980
1981 response->completion_code = completion_code;
1982 response->sensor_data_size = sensor_data_size;
1983 response->sensor_operational_state = sensor_operational_state;
1984 response->sensor_event_message_enable = sensor_event_message_enable;
1985 response->present_state = present_state;
1986 response->previous_state = previous_state;
1987 response->event_state = event_state;
1988
1989 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1990 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1991 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1992 return PLDM_ERROR_INVALID_LENGTH;
1993 }
1994 response->present_reading[0] = *present_reading;
1995
1996 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1997 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1998 if (payload_length !=
1999 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2000 return PLDM_ERROR_INVALID_LENGTH;
2001 }
2002 uint16_t val = *(uint16_t *)present_reading;
2003 val = htole16(val);
2004 memcpy(response->present_reading, &val, 2);
2005
2006 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2007 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2008 if (payload_length !=
2009 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2010 return PLDM_ERROR_INVALID_LENGTH;
2011 }
2012 uint32_t val = *(uint32_t *)present_reading;
2013 val = htole32(val);
2014 memcpy(response->present_reading, &val, 4);
2015 }
2016
2017 return PLDM_SUCCESS;
2018}
2019
2020int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2021 size_t payload_length, uint16_t *sensor_id,
2022 uint8_t *rearm_event_state)
2023{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302024 struct pldm_msgbuf _buf;
2025 struct pldm_msgbuf *buf = &_buf;
2026 int rc;
2027
Andrew Jeffery9c766792022-08-10 23:12:49 +09302028 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2029 return PLDM_ERROR_INVALID_DATA;
2030 }
2031
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302032 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2033 msg->payload, payload_length);
2034 if (rc) {
2035 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302036 }
2037
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302038 pldm_msgbuf_extract(buf, sensor_id);
2039 pldm_msgbuf_extract(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302040
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302041 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302042}
2043
2044int encode_set_event_receiver_req(uint8_t instance_id,
2045 uint8_t event_message_global_enable,
2046 uint8_t transport_protocol_type,
2047 uint8_t event_receiver_address_info,
2048 uint16_t heartbeat_timer,
2049 struct pldm_msg *msg)
2050{
2051 if (msg == NULL) {
2052 return PLDM_ERROR_INVALID_DATA;
2053 }
2054
2055 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2056 return PLDM_ERROR_INVALID_DATA;
2057 }
2058
2059 struct pldm_header_info header = {0};
2060 header.msg_type = PLDM_REQUEST;
2061 header.instance = instance_id;
2062 header.pldm_type = PLDM_PLATFORM;
2063 header.command = PLDM_SET_EVENT_RECEIVER;
2064
2065 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2066 if (rc != PLDM_SUCCESS) {
2067 return rc;
2068 }
2069
2070 struct pldm_set_event_receiver_req *request =
2071 (struct pldm_set_event_receiver_req *)msg->payload;
2072 request->event_message_global_enable = event_message_global_enable;
2073
2074 request->transport_protocol_type = transport_protocol_type;
2075 request->event_receiver_address_info = event_receiver_address_info;
2076
2077 if (event_message_global_enable ==
2078 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2079 if (heartbeat_timer == 0) {
2080 return PLDM_ERROR_INVALID_DATA;
2081 }
2082 request->heartbeat_timer = htole16(heartbeat_timer);
2083 }
2084
2085 return PLDM_SUCCESS;
2086}
2087
2088int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2089 size_t payload_length,
2090 uint8_t *completion_code)
2091{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302092 struct pldm_msgbuf _buf;
2093 struct pldm_msgbuf *buf = &_buf;
2094 int rc;
2095
Andrew Jeffery9c766792022-08-10 23:12:49 +09302096 if (msg == NULL || completion_code == NULL) {
2097 return PLDM_ERROR_INVALID_DATA;
2098 }
2099
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302100 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2101 msg->payload, payload_length);
2102 if (rc) {
2103 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302104 }
2105
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302106 pldm_msgbuf_extract(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302107
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302108 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302109}
2110
2111int decode_set_event_receiver_req(const struct pldm_msg *msg,
2112 size_t payload_length,
2113 uint8_t *event_message_global_enable,
2114 uint8_t *transport_protocol_type,
2115 uint8_t *event_receiver_address_info,
2116 uint16_t *heartbeat_timer)
2117
2118{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302119 struct pldm_msgbuf _buf;
2120 struct pldm_msgbuf *buf = &_buf;
2121 int rc;
2122
Andrew Jeffery9c766792022-08-10 23:12:49 +09302123 if (msg == NULL || event_message_global_enable == NULL ||
2124 transport_protocol_type == NULL ||
2125 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2126 return PLDM_ERROR_INVALID_DATA;
2127 }
2128
Andrew Jeffery9667f582023-04-14 00:39:21 +09302129 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2130 msg->payload, payload_length);
2131 if (rc) {
2132 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302133 }
2134
Andrew Jeffery9667f582023-04-14 00:39:21 +09302135 pldm_msgbuf_extract(buf, event_message_global_enable);
2136 pldm_msgbuf_extract(buf, transport_protocol_type);
2137 pldm_msgbuf_extract(buf, event_receiver_address_info);
2138 pldm_msgbuf_extract(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302139
Andrew Jeffery9667f582023-04-14 00:39:21 +09302140 rc = pldm_msgbuf_destroy(buf);
2141 if (rc) {
2142 return rc;
2143 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302144
Andrew Jeffery9c766792022-08-10 23:12:49 +09302145 if ((*event_message_global_enable ==
2146 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2147 (*heartbeat_timer == 0)) {
2148 return PLDM_ERROR_INVALID_DATA;
2149 }
2150
Andrew Jeffery9c766792022-08-10 23:12:49 +09302151 return PLDM_SUCCESS;
2152}
2153
2154int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2155 struct pldm_msg *msg)
2156
2157{
2158 if (msg == NULL) {
2159 return PLDM_ERROR_INVALID_DATA;
2160 }
2161
2162 struct pldm_header_info header = {0};
2163 header.instance = instance_id;
2164 header.msg_type = PLDM_RESPONSE;
2165 header.pldm_type = PLDM_PLATFORM;
2166 header.command = PLDM_SET_EVENT_RECEIVER;
2167
2168 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2169 if (rc != PLDM_SUCCESS) {
2170 return rc;
2171 }
2172
2173 msg->payload[0] = completion_code;
2174
2175 return PLDM_SUCCESS;
2176}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002177
2178int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2179 uint8_t format_version,
2180 uint8_t transfer_operation_flag,
2181 uint32_t data_transfer_handle,
2182 uint16_t event_id_to_acknowledge,
2183 struct pldm_msg *msg,
2184 size_t payload_length)
2185{
2186 struct pldm_msgbuf _buf;
2187 struct pldm_msgbuf *buf = &_buf;
2188 int rc;
2189
2190 if (msg == NULL) {
2191 return PLDM_ERROR_INVALID_DATA;
2192 }
2193
2194 struct pldm_header_info header = {0};
2195 header.msg_type = PLDM_REQUEST;
2196 header.instance = instance_id;
2197 header.pldm_type = PLDM_PLATFORM;
2198 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2199
2200 rc = pack_pldm_header(&header, &(msg->hdr));
2201 if (rc != PLDM_SUCCESS) {
2202 return rc;
2203 }
2204
2205 rc = pldm_msgbuf_init(
2206 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2207 msg->payload, payload_length);
2208 if (rc) {
2209 return rc;
2210 }
2211
2212 pldm_msgbuf_insert(buf, format_version);
2213 pldm_msgbuf_insert(buf, transfer_operation_flag);
2214 pldm_msgbuf_insert(buf, data_transfer_handle);
2215 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2216
2217 return pldm_msgbuf_destroy(buf);
2218}
2219
2220int decode_poll_for_platform_event_message_resp(
2221 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
2222 uint8_t *tid, uint16_t *event_id, uint32_t *next_data_transfer_handle,
2223 uint8_t *transfer_flag, uint8_t *event_class, uint32_t *event_data_size,
2224 void **event_data, uint32_t *event_data_integrity_checksum)
2225{
2226 struct pldm_msgbuf _buf;
2227 struct pldm_msgbuf *buf = &_buf;
2228 int rc;
2229
2230 if (msg == NULL || completion_code == NULL || tid == NULL ||
2231 event_id == NULL || next_data_transfer_handle == NULL ||
2232 transfer_flag == NULL || event_class == NULL ||
2233 event_data_size == NULL || event_data == NULL ||
2234 event_data_integrity_checksum == NULL) {
2235 return PLDM_ERROR_INVALID_DATA;
2236 }
2237
2238 rc = pldm_msgbuf_init(
2239 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2240 msg->payload, payload_length);
2241 if (rc) {
2242 return rc;
2243 }
2244
2245 rc = pldm_msgbuf_extract(buf, completion_code);
2246 if (rc) {
2247 return rc;
2248 }
2249 if (PLDM_SUCCESS != *completion_code) {
2250 return *completion_code;
2251 }
2252
2253 pldm_msgbuf_extract(buf, tid);
2254 rc = pldm_msgbuf_extract(buf, event_id);
2255 if (rc) {
2256 return rc;
2257 }
2258 if ((*event_id == 0) || (*event_id == 0xffff)) {
2259 return PLDM_SUCCESS;
2260 }
2261
2262 pldm_msgbuf_extract(buf, next_data_transfer_handle);
2263 rc = pldm_msgbuf_extract(buf, transfer_flag);
2264 if (rc) {
2265 return rc;
2266 }
2267
2268 pldm_msgbuf_extract(buf, event_class);
2269 rc = pldm_msgbuf_extract(buf, event_data_size);
2270 if (rc) {
2271 return rc;
2272 }
2273 if (*event_data_size > payload_length) {
2274 return PLDM_ERROR_INVALID_DATA;
2275 }
2276
2277 if (*event_data_size > 0) {
2278 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2279 }
2280
2281 if (*transfer_flag == PLDM_END ||
2282 *transfer_flag == PLDM_START_AND_END) {
2283 pldm_msgbuf_extract(buf, event_data_integrity_checksum);
2284 }
2285
2286 return pldm_msgbuf_destroy_consumed(buf);
2287}