blob: 8619772e45cadc1ae3f447c4d807c69fd22c53ae [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
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093025LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093026int encode_state_effecter_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093027 struct pldm_state_effecter_pdr *const effecter,
28 const size_t allocation_size,
29 const struct state_effecter_possible_states *const possible_states,
30 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093031{
32 // Encode possible states
33
34 size_t calculated_possible_states_size = 0;
35
36 {
37 char *states_ptr = (char *)possible_states;
38 char *const begin_states_ptr = states_ptr;
39
40 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
41 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093042 (struct state_effecter_possible_states *)
43 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093044
45 HTOLE16(states->state_set_id);
46
47 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093048 (sizeof(*states) - sizeof(states->states) +
49 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093050 }
51
52 calculated_possible_states_size = states_ptr - begin_states_ptr;
53 }
54
55 // Check lengths
56
57 if (possible_states_size != calculated_possible_states_size) {
58 *actual_size = 0;
59 return PLDM_ERROR;
60 }
61
62 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093063 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
64 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093065
66 if (allocation_size < *actual_size) {
67 *actual_size = 0;
68 return PLDM_ERROR_INVALID_LENGTH;
69 }
70
71 // Encode rest of PDR
72
73 effecter->hdr.version = 1;
74 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
75 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
76
77 memcpy(effecter->possible_states, possible_states,
78 possible_states_size);
79
80 // Convert effecter PDR body
81 HTOLE16(effecter->terminus_handle);
82 HTOLE16(effecter->effecter_id);
83 HTOLE16(effecter->entity_type);
84 HTOLE16(effecter->entity_instance);
85 HTOLE16(effecter->container_id);
86 HTOLE16(effecter->effecter_semantic_id);
87
88 // Convert header
89 HTOLE32(effecter->hdr.record_handle);
90 HTOLE16(effecter->hdr.record_change_num);
91 HTOLE16(effecter->hdr.length);
92
93 return PLDM_SUCCESS;
94}
95
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093096LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093097int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093098 struct pldm_state_sensor_pdr *const sensor,
99 const size_t allocation_size,
100 const struct state_sensor_possible_states *const possible_states,
101 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930102{
103 // Encode possible states
104
105 size_t calculated_possible_states_size = 0;
106
107 {
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930108 char *states_ptr = (char *)possible_states;
109 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930110
111 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
112 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930113 (struct state_sensor_possible_states *)
114 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930115
116 HTOLE16(states->state_set_id);
117
118 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930119 (sizeof(*states) - sizeof(states->states) +
120 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930121 }
122
123 calculated_possible_states_size = states_ptr - begin_states_ptr;
124 }
125
126 // Check lengths
127
128 if (possible_states_size != calculated_possible_states_size) {
129 *actual_size = 0;
130 return PLDM_ERROR;
131 }
132
133 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
134 possible_states_size - sizeof(sensor->possible_states));
135
136 if (allocation_size < *actual_size) {
137 *actual_size = 0;
138 return PLDM_ERROR_INVALID_LENGTH;
139 }
140
141 // Encode rest of PDR
142
143 sensor->hdr.version = 1;
144 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
145 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
146
147 memcpy(sensor->possible_states, possible_states, possible_states_size);
148
149 // Convert sensor PDR body
150 HTOLE16(sensor->terminus_handle);
151 HTOLE16(sensor->sensor_id);
152 HTOLE16(sensor->entity_type);
153 HTOLE16(sensor->entity_instance);
154 HTOLE16(sensor->container_id);
155
156 // Convert header
157 HTOLE32(sensor->hdr.record_handle);
158 HTOLE16(sensor->hdr.record_change_num);
159 HTOLE16(sensor->hdr.length);
160
161 return PLDM_SUCCESS;
162}
163
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930164LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930165int encode_set_state_effecter_states_resp(uint8_t instance_id,
166 uint8_t completion_code,
167 struct pldm_msg *msg)
168{
169 if (msg == NULL) {
170 return PLDM_ERROR_INVALID_DATA;
171 }
172
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930173 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930174 header.msg_type = PLDM_RESPONSE;
175 header.instance = instance_id;
176 header.pldm_type = PLDM_PLATFORM;
177 header.command = PLDM_SET_STATE_EFFECTER_STATES;
178
179 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
180 if (rc != PLDM_SUCCESS) {
181 return rc;
182 }
183
184 msg->payload[0] = completion_code;
185
186 return PLDM_SUCCESS;
187}
188
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930189LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930190int encode_set_state_effecter_states_req(uint8_t instance_id,
191 uint16_t effecter_id,
192 uint8_t comp_effecter_count,
193 set_effecter_state_field *field,
194 struct pldm_msg *msg)
195{
196 if (msg == NULL) {
197 return PLDM_ERROR_INVALID_DATA;
198 }
199
200 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
201 field == NULL) {
202 return PLDM_ERROR_INVALID_DATA;
203 }
204
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930205 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930206 header.msg_type = PLDM_REQUEST;
207 header.instance = instance_id;
208 header.pldm_type = PLDM_PLATFORM;
209 header.command = PLDM_SET_STATE_EFFECTER_STATES;
210
211 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
212 if (rc != PLDM_SUCCESS) {
213 return rc;
214 }
215
216 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930217 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930218 effecter_id = htole16(effecter_id);
219 request->effecter_id = effecter_id;
220 request->comp_effecter_count = comp_effecter_count;
221 memcpy(request->field, field,
222 (sizeof(set_effecter_state_field) * comp_effecter_count));
223
224 return PLDM_SUCCESS;
225}
226
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930227LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930228int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
229 size_t payload_length,
230 uint8_t *completion_code)
231{
232 if (msg == NULL || completion_code == NULL) {
233 return PLDM_ERROR_INVALID_DATA;
234 }
235
236 *completion_code = msg->payload[0];
237 if (PLDM_SUCCESS != *completion_code) {
238 return PLDM_SUCCESS;
239 }
240
241 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
242 return PLDM_ERROR_INVALID_LENGTH;
243 }
244
245 return PLDM_SUCCESS;
246}
247
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930248#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930249LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930250int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
251 size_t payload_length,
252 uint16_t *effecter_id,
253 uint8_t *comp_effecter_count,
254 set_effecter_state_field *field)
255{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930256 struct pldm_msgbuf _buf;
257 struct pldm_msgbuf *buf = &_buf;
258 int rc;
259 int i;
260
Andrew Jeffery9c766792022-08-10 23:12:49 +0930261 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
262 field == NULL) {
263 return PLDM_ERROR_INVALID_DATA;
264 }
265
266 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
267 return PLDM_ERROR_INVALID_LENGTH;
268 }
269
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930270 rc = pldm_msgbuf_init(buf, PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
271 msg->payload, payload_length);
272 if (rc) {
273 return rc;
274 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930275
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930276 pldm_msgbuf_extract(buf, effecter_id);
277 pldm_msgbuf_extract(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930278
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930279 if (*comp_effecter_count > 8) {
280 return PLDM_ERROR_INVALID_DATA;
281 }
282
283 for (i = 0; i < *comp_effecter_count; i++) {
284 pldm_msgbuf_extract(buf, &field[i].set_request);
285 pldm_msgbuf_extract(buf, &field[i].effecter_state);
286 }
287
288 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930289}
290
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930291LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930292int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
293 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
294 uint8_t *transfer_op_flag, uint16_t *request_cnt,
295 uint16_t *record_chg_num)
296{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930297 struct pldm_msgbuf _buf;
298 struct pldm_msgbuf *buf = &_buf;
299 int rc;
300
Andrew Jeffery9c766792022-08-10 23:12:49 +0930301 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
302 transfer_op_flag == NULL || request_cnt == NULL ||
303 record_chg_num == NULL) {
304 return PLDM_ERROR_INVALID_DATA;
305 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930306
Andrew Jeffery9c766792022-08-10 23:12:49 +0930307 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
308 return PLDM_ERROR_INVALID_LENGTH;
309 }
310
Andrew Jeffery891781e2023-04-04 11:04:18 +0930311 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
312 payload_length);
313 if (rc) {
314 return rc;
315 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930316
Andrew Jeffery891781e2023-04-04 11:04:18 +0930317 pldm_msgbuf_extract(buf, record_hndl);
318 pldm_msgbuf_extract(buf, data_transfer_hndl);
319 pldm_msgbuf_extract(buf, transfer_op_flag);
320 pldm_msgbuf_extract(buf, request_cnt);
321 pldm_msgbuf_extract(buf, record_chg_num);
322
323 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930324}
325
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930326LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930327int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
328 uint32_t next_record_hndl,
329 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
330 uint16_t resp_cnt, const uint8_t *record_data,
331 uint8_t transfer_crc, struct pldm_msg *msg)
332{
333 if (msg == NULL) {
334 return PLDM_ERROR_INVALID_DATA;
335 }
336
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930337 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930338 header.msg_type = PLDM_RESPONSE;
339 header.instance = instance_id;
340 header.pldm_type = PLDM_PLATFORM;
341 header.command = PLDM_GET_PDR;
342
343 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
344 if (rc != PLDM_SUCCESS) {
345 return rc;
346 }
347
348 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930349 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930350 response->completion_code = completion_code;
351
352 if (response->completion_code == PLDM_SUCCESS) {
353 response->next_record_handle = htole32(next_record_hndl);
354 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930355 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930356 response->transfer_flag = transfer_flag;
357 response->response_count = htole16(resp_cnt);
358 if (record_data != NULL && resp_cnt > 0) {
359 memcpy(response->record_data, record_data, resp_cnt);
360 }
361 if (transfer_flag == PLDM_END) {
362 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930363 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
364 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930365 *dst = transfer_crc;
366 }
367 }
368
369 return PLDM_SUCCESS;
370}
371
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930372LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930373int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930374 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
375 const uint8_t *update_time, const uint8_t *oem_update_time,
376 uint32_t record_count, uint32_t repository_size,
377 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
378 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930379{
380 if (msg == NULL) {
381 return PLDM_ERROR_INVALID_DATA;
382 }
383
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930384 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930385 header.msg_type = PLDM_RESPONSE;
386 header.instance = instance_id;
387 header.pldm_type = PLDM_PLATFORM;
388 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
389
390 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
391 if (rc != PLDM_SUCCESS) {
392 return rc;
393 }
394
395 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930396 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930397 response->completion_code = completion_code;
398
399 if (response->completion_code == PLDM_SUCCESS) {
400 response->repository_state = repository_state;
401 if (update_time != NULL) {
402 memcpy(response->update_time, update_time,
403 PLDM_TIMESTAMP104_SIZE);
404 }
405 if (oem_update_time != NULL) {
406 memcpy(response->oem_update_time, oem_update_time,
407 PLDM_TIMESTAMP104_SIZE);
408 }
409 response->record_count = htole32(record_count);
410 response->repository_size = htole32(repository_size);
411 response->largest_record_size = htole32(largest_record_size);
412 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930413 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930414 }
415
416 return PLDM_SUCCESS;
417}
418
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930419LIBPLDM_ABI_STABLE
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800420int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930421 const struct pldm_msg *msg, size_t payload_length,
422 uint8_t *completion_code, uint8_t *repository_state,
423 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
424 uint32_t *repository_size, uint32_t *largest_record_size,
425 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800426{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930427 struct pldm_msgbuf _buf;
428 struct pldm_msgbuf *buf = &_buf;
429 int rc;
430
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800431 if (msg == NULL || completion_code == NULL ||
432 repository_state == NULL || update_time == NULL ||
433 oem_update_time == NULL || record_count == NULL ||
434 repository_size == NULL || largest_record_size == NULL ||
435 data_transfer_handle_timeout == NULL) {
436 return PLDM_ERROR_INVALID_DATA;
437 }
438
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930439 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
440 msg->payload, payload_length);
441 if (rc) {
442 return rc;
443 }
444
445 pldm_msgbuf_extract(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800446 if (PLDM_SUCCESS != *completion_code) {
447 return PLDM_SUCCESS;
448 }
449
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930450 pldm_msgbuf_extract(buf, repository_state);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800451 if (*repository_state > PLDM_FAILED) {
452 return PLDM_ERROR_INVALID_DATA;
453 }
454
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930455 pldm_msgbuf_extract_array(buf, update_time, PLDM_TIMESTAMP104_SIZE);
456 pldm_msgbuf_extract_array(buf, oem_update_time, PLDM_TIMESTAMP104_SIZE);
457 pldm_msgbuf_extract(buf, record_count);
458 pldm_msgbuf_extract(buf, repository_size);
459 pldm_msgbuf_extract(buf, largest_record_size);
460 pldm_msgbuf_extract(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800461
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930462 return pldm_msgbuf_destroy(buf);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800463}
464
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930465LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930466int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
467 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
468 uint16_t request_cnt, uint16_t record_chg_num,
469 struct pldm_msg *msg, size_t payload_length)
470{
471 if (msg == NULL) {
472 return PLDM_ERROR_INVALID_DATA;
473 }
474
475 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
476 return PLDM_ERROR_INVALID_LENGTH;
477 }
478
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930479 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930480 header.msg_type = PLDM_REQUEST;
481 header.instance = instance_id;
482 header.pldm_type = PLDM_PLATFORM;
483 header.command = PLDM_GET_PDR;
484
485 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
486 if (rc != PLDM_SUCCESS) {
487 return rc;
488 }
489
490 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930491 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930492 request->record_handle = htole32(record_hndl);
493 request->data_transfer_handle = htole32(data_transfer_hndl);
494 request->transfer_op_flag = transfer_op_flag;
495 request->request_count = htole16(request_cnt);
496 request->record_change_number = htole16(record_chg_num);
497
498 return PLDM_SUCCESS;
499}
500
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930501LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930502int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
503 uint8_t *completion_code, uint32_t *next_record_hndl,
504 uint32_t *next_data_transfer_hndl,
505 uint8_t *transfer_flag, uint16_t *resp_cnt,
506 uint8_t *record_data, size_t record_data_length,
507 uint8_t *transfer_crc)
508{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930509 struct pldm_msgbuf _buf;
510 struct pldm_msgbuf *buf = &_buf;
511 int rc;
512
Andrew Jeffery9c766792022-08-10 23:12:49 +0930513 if (msg == NULL || completion_code == NULL ||
514 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
515 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
516 return PLDM_ERROR_INVALID_DATA;
517 }
518
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930519 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
520 payload_length);
521 if (rc) {
522 return rc;
523 }
524
525 pldm_msgbuf_extract(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930526 if (PLDM_SUCCESS != *completion_code) {
527 return PLDM_SUCCESS;
528 }
529
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930530 pldm_msgbuf_extract(buf, next_record_hndl);
531 pldm_msgbuf_extract(buf, next_data_transfer_hndl);
532 pldm_msgbuf_extract(buf, transfer_flag);
533 rc = pldm_msgbuf_extract(buf, resp_cnt);
534 if (rc) {
535 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930536 }
537
538 if (*resp_cnt > 0 && record_data != NULL) {
539 if (record_data_length < *resp_cnt) {
540 return PLDM_ERROR_INVALID_LENGTH;
541 }
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930542 pldm_msgbuf_extract_array(buf, record_data, *resp_cnt);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930543 }
544
545 if (*transfer_flag == PLDM_END) {
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930546 pldm_msgbuf_extract(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930547 }
548
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930549 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930550}
551
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930552LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930553int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
554 size_t payload_length,
555 uint16_t *effecter_id,
556 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930557 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930558{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930559 struct pldm_msgbuf _buf;
560 struct pldm_msgbuf *buf = &_buf;
561 int rc;
562
Andrew Jeffery9c766792022-08-10 23:12:49 +0930563 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
564 effecter_value == NULL) {
565 return PLDM_ERROR_INVALID_DATA;
566 }
567
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930568 rc = pldm_msgbuf_init(buf,
569 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
570 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930571 if (rc) {
572 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930573 }
574
Andrew Jeffery3884c442023-04-12 11:13:24 +0930575 pldm_msgbuf_extract(buf, effecter_id);
576 rc = pldm_msgbuf_extract(buf, effecter_data_size);
577 if (rc) {
578 return PLDM_ERROR_INVALID_DATA;
579 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930580
581 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
582 return PLDM_ERROR_INVALID_DATA;
583 }
584
Andrew Jeffery3884c442023-04-12 11:13:24 +0930585 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
586 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930587
Andrew Jeffery3884c442023-04-12 11:13:24 +0930588 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930589}
590
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930591LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930592int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
593 uint8_t completion_code,
594 struct pldm_msg *msg,
595 size_t payload_length)
596{
597 if (msg == NULL) {
598 return PLDM_ERROR_INVALID_DATA;
599 }
600
601 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
602 return PLDM_ERROR_INVALID_LENGTH;
603 }
604
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930605 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930606 header.msg_type = PLDM_RESPONSE;
607 header.instance = instance_id;
608 header.pldm_type = PLDM_PLATFORM;
609 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
610
611 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
612 if (rc != PLDM_SUCCESS) {
613 return rc;
614 }
615
616 msg->payload[0] = completion_code;
617
618 return rc;
619}
620
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930621LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930622int encode_set_numeric_effecter_value_req(uint8_t instance_id,
623 uint16_t effecter_id,
624 uint8_t effecter_data_size,
625 const uint8_t *effecter_value,
626 struct pldm_msg *msg,
627 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930628{
629 if (msg == NULL || effecter_value == NULL) {
630 return PLDM_ERROR_INVALID_DATA;
631 }
632
633 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
634 return PLDM_ERROR_INVALID_DATA;
635 }
636
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930637 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930638 header.msg_type = PLDM_REQUEST;
639 header.instance = instance_id;
640 header.pldm_type = PLDM_PLATFORM;
641 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
642
643 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
644 if (rc != PLDM_SUCCESS) {
645 return rc;
646 }
647
648 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930649 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930650 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
651 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
652 if (payload_length !=
653 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
654 return PLDM_ERROR_INVALID_LENGTH;
655 }
656 request->effecter_value[0] = *effecter_value;
657 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
658 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
659 if (payload_length !=
660 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
661 return PLDM_ERROR_INVALID_LENGTH;
662 }
663
664 uint16_t val = *(uint16_t *)(effecter_value);
665 val = htole16(val);
666 memcpy(request->effecter_value, &val, sizeof(uint16_t));
667
668 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
669 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
670 if (payload_length !=
671 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
672 return PLDM_ERROR_INVALID_LENGTH;
673 }
674
675 uint32_t val = *(uint32_t *)(effecter_value);
676 val = htole32(val);
677 memcpy(request->effecter_value, &val, sizeof(uint32_t));
678 }
679
680 request->effecter_id = htole16(effecter_id);
681 request->effecter_data_size = effecter_data_size;
682
683 return PLDM_SUCCESS;
684}
685
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930686LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930687int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
688 size_t payload_length,
689 uint8_t *completion_code)
690{
691 if (msg == NULL || completion_code == NULL) {
692 return PLDM_ERROR_INVALID_DATA;
693 }
694
695 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
696 return PLDM_ERROR_INVALID_LENGTH;
697 }
698
699 *completion_code = msg->payload[0];
700
701 return PLDM_SUCCESS;
702}
703
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930704LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930705int encode_get_state_sensor_readings_resp(uint8_t instance_id,
706 uint8_t completion_code,
707 uint8_t comp_sensor_count,
708 get_sensor_state_field *field,
709 struct pldm_msg *msg)
710{
711 if (msg == NULL) {
712 return PLDM_ERROR_INVALID_DATA;
713 }
714
715 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
716 return PLDM_ERROR_INVALID_DATA;
717 }
718
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930719 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930720 header.msg_type = PLDM_RESPONSE;
721 header.instance = instance_id;
722 header.pldm_type = PLDM_PLATFORM;
723 header.command = PLDM_GET_STATE_SENSOR_READINGS;
724
725 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
726 if (rc != PLDM_SUCCESS) {
727 return rc;
728 }
729
730 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930731 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930732
733 response->completion_code = completion_code;
734 response->comp_sensor_count = comp_sensor_count;
735 memcpy(response->field, field,
736 (sizeof(get_sensor_state_field) * comp_sensor_count));
737
738 return PLDM_SUCCESS;
739}
740
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930741LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930742int encode_get_state_sensor_readings_req(uint8_t instance_id,
743 uint16_t sensor_id,
744 bitfield8_t sensor_rearm,
745 uint8_t reserved, struct pldm_msg *msg)
746{
747 if (msg == NULL) {
748 return PLDM_ERROR_INVALID_DATA;
749 }
750
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930751 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930752 header.msg_type = PLDM_REQUEST;
753 header.instance = instance_id;
754 header.pldm_type = PLDM_PLATFORM;
755 header.command = PLDM_GET_STATE_SENSOR_READINGS;
756
757 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
758 if (rc != PLDM_SUCCESS) {
759 return rc;
760 }
761
762 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930763 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930764
765 request->sensor_id = htole16(sensor_id);
766 request->reserved = reserved;
767 request->sensor_rearm = sensor_rearm;
768
769 return PLDM_SUCCESS;
770}
771
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930772LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930773int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
774 size_t payload_length,
775 uint8_t *completion_code,
776 uint8_t *comp_sensor_count,
777 get_sensor_state_field *field)
778{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930779 struct pldm_msgbuf _buf;
780 struct pldm_msgbuf *buf = &_buf;
781 uint8_t i;
782 int rc;
783
Andrew Jeffery9c766792022-08-10 23:12:49 +0930784 if (msg == NULL || completion_code == NULL ||
785 comp_sensor_count == NULL || field == NULL) {
786 return PLDM_ERROR_INVALID_DATA;
787 }
788
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930789 rc = pldm_msgbuf_init(buf,
790 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
791 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930792 if (rc) {
793 return rc;
794 }
795
796 rc = pldm_msgbuf_extract(buf, completion_code);
797 if (rc) {
798 return rc;
799 }
800
Andrew Jeffery9c766792022-08-10 23:12:49 +0930801 if (PLDM_SUCCESS != *completion_code) {
802 return PLDM_SUCCESS;
803 }
804
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930805 rc = pldm_msgbuf_extract(buf, comp_sensor_count);
806 if (rc) {
807 return rc;
808 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930809
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930810 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930811 return PLDM_ERROR_INVALID_DATA;
812 }
813
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930814 for (i = 0; i < *comp_sensor_count; i++) {
815 pldm_msgbuf_extract(buf, &field[i].sensor_op_state);
816 pldm_msgbuf_extract(buf, &field[i].present_state);
817 pldm_msgbuf_extract(buf, &field[i].previous_state);
818 pldm_msgbuf_extract(buf, &field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930819 }
820
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930821 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930822}
823
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930824LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930825int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
826 size_t payload_length,
827 uint16_t *sensor_id,
828 bitfield8_t *sensor_rearm,
829 uint8_t *reserved)
830{
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930831 struct pldm_msgbuf _buf;
832 struct pldm_msgbuf *buf = &_buf;
833 int rc;
834
Andrew Jeffery9c766792022-08-10 23:12:49 +0930835 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
836 return PLDM_ERROR_INVALID_DATA;
837 }
838
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930839 rc = pldm_msgbuf_init(buf, PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
840 msg->payload, payload_length);
841 if (rc) {
842 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930843 }
844
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930845 pldm_msgbuf_extract(buf, sensor_id);
846 pldm_msgbuf_extract(buf, &sensor_rearm->byte);
847 pldm_msgbuf_extract(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930848
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930849 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930850}
851
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930852LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930853int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930854 struct pldm_sensor_event_data *const event_data,
855 const size_t event_data_size, const uint16_t sensor_id,
856 const enum sensor_event_class_states sensor_event_class,
857 const uint8_t sensor_offset, const uint8_t event_state,
858 const uint8_t previous_event_state,
859 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930860{
861 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930862 (sizeof(*event_data) - sizeof(event_data->event_class) +
863 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930864
865 if (!event_data) {
866 return PLDM_SUCCESS;
867 }
868
869 if (event_data_size < *actual_event_data_size) {
870 *actual_event_data_size = 0;
871 return PLDM_ERROR_INVALID_LENGTH;
872 }
873
874 event_data->sensor_id = htole16(sensor_id);
875 event_data->sensor_event_class_type = sensor_event_class;
876
877 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930878 (struct pldm_sensor_event_state_sensor_state *)
879 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930880
881 state_data->sensor_offset = sensor_offset;
882 state_data->event_state = event_state;
883 state_data->previous_event_state = previous_event_state;
884
885 return PLDM_SUCCESS;
886}
887
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930888LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930889int decode_platform_event_message_req(const struct pldm_msg *msg,
890 size_t payload_length,
891 uint8_t *format_version, uint8_t *tid,
892 uint8_t *event_class,
893 size_t *event_data_offset)
894{
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930895 struct pldm_msgbuf _buf;
896 struct pldm_msgbuf *buf = &_buf;
897 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930898
899 if (msg == NULL || format_version == NULL || tid == NULL ||
900 event_class == NULL || event_data_offset == NULL) {
901 return PLDM_ERROR_INVALID_DATA;
902 }
903
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930904 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
905 msg->payload, payload_length);
906 if (rc) {
907 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930908 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930909
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930910 pldm_msgbuf_extract(buf, format_version);
911 pldm_msgbuf_extract(buf, tid);
912 pldm_msgbuf_extract(buf, event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930913 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930914 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930915
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930916 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930917}
918
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930919LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700920int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930921 const struct pldm_msg *msg, size_t payload_length,
922 uint8_t *format_version, uint8_t *transfer_operation_flag,
923 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700924{
925 struct pldm_msgbuf _buf;
926 struct pldm_msgbuf *buf = &_buf;
927 int rc;
928
929 if (msg == NULL) {
930 return PLDM_ERROR_INVALID_DATA;
931 }
932
933 rc = pldm_msgbuf_init(buf,
934 PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
935 msg->payload, payload_length);
936 if (rc) {
937 return rc;
938 }
939
940 pldm_msgbuf_extract(buf, format_version);
941 rc = pldm_msgbuf_extract(buf, transfer_operation_flag);
942 if (rc) {
943 return rc;
944 }
945 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
946 return PLDM_ERROR_INVALID_DATA;
947 }
948
949 pldm_msgbuf_extract(buf, data_transfer_handle);
950 rc = pldm_msgbuf_extract(buf, event_id_to_acknowledge);
951 if (rc) {
952 return rc;
953 }
954
955 if (!(((*transfer_operation_flag == PLDM_GET_NEXTPART) &&
956 (*event_id_to_acknowledge == 0xFFFF)) ||
957 ((*transfer_operation_flag == PLDM_GET_FIRSTPART) &&
958 (*event_id_to_acknowledge == 0x000)) ||
959 (*transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY))) {
960 return PLDM_ERROR_INVALID_DATA;
961 }
962
963 return pldm_msgbuf_destroy(buf);
964}
965
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930966LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930967int encode_platform_event_message_resp(uint8_t instance_id,
968 uint8_t completion_code,
969 uint8_t platform_event_status,
970 struct pldm_msg *msg)
971{
972 if (msg == NULL) {
973 return PLDM_ERROR_INVALID_DATA;
974 }
975
976 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
977 return PLDM_ERROR_INVALID_DATA;
978 }
979
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930980 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930981 header.msg_type = PLDM_RESPONSE;
982 header.instance = instance_id;
983 header.pldm_type = PLDM_PLATFORM;
984 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
985
986 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
987 if (rc != PLDM_SUCCESS) {
988 return rc;
989 }
990
991 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930992 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930993 response->completion_code = completion_code;
994 response->platform_event_status = platform_event_status;
995
996 return PLDM_SUCCESS;
997}
998
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930999LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001000int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301001 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1002 uint16_t event_id, uint32_t next_data_transfer_handle,
1003 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1004 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1005 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001006{
1007 struct pldm_msgbuf _buf;
1008 struct pldm_msgbuf *buf = &_buf;
1009 int rc;
1010
1011 if (!msg) {
1012 return PLDM_ERROR_INVALID_DATA;
1013 }
1014
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301015 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001016 header.msg_type = PLDM_RESPONSE;
1017 header.instance = instance_id;
1018 header.pldm_type = PLDM_PLATFORM;
1019 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1020
1021 rc = pack_pldm_header(&header, &(msg->hdr));
1022 if (rc != PLDM_SUCCESS) {
1023 return rc;
1024 }
1025
1026 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301027 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1028 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001029 if (rc) {
1030 return rc;
1031 }
1032
1033 pldm_msgbuf_insert(buf, completion_code);
1034 pldm_msgbuf_insert(buf, tid);
1035 pldm_msgbuf_insert(buf, event_id);
1036
1037 if (event_id == 0xffff || event_id == 0x0000) {
1038 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1039 payload_length) {
1040 return PLDM_ERROR_INVALID_LENGTH;
1041 }
1042 return pldm_msgbuf_destroy(buf);
1043 }
1044
1045 if ((event_data == NULL) && (event_data_size > 0)) {
1046 return PLDM_ERROR_INVALID_DATA;
1047 }
1048
1049 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1050 pldm_msgbuf_insert(buf, transfer_flag);
1051 pldm_msgbuf_insert(buf, event_class);
1052 pldm_msgbuf_insert(buf, event_data_size);
1053
1054 if ((event_data_size > 0) && event_data) {
1055 pldm_msgbuf_insert_array(buf, event_data, event_data_size);
1056 }
1057
1058 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1059 pldm_msgbuf_insert(buf, checksum);
1060 }
1061
1062 return pldm_msgbuf_destroy(buf);
1063}
1064
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301065LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301066int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301067 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1068 uint8_t event_class, const uint8_t *event_data,
1069 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301070
1071{
1072 if (format_version != 1) {
1073 return PLDM_ERROR_INVALID_DATA;
1074 }
1075
1076 if (msg == NULL || event_data == NULL) {
1077 return PLDM_ERROR_INVALID_DATA;
1078 }
1079
1080 if (event_data_length == 0) {
1081 return PLDM_ERROR_INVALID_DATA;
1082 }
1083
1084 if (payload_length !=
1085 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1086 return PLDM_ERROR_INVALID_LENGTH;
1087 }
1088
1089 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
1090 !(event_class >= 0xF0 && event_class <= 0xFE)) {
1091 return PLDM_ERROR_INVALID_DATA;
1092 }
1093
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301094 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301095 header.msg_type = PLDM_REQUEST;
1096 header.instance = instance_id;
1097 header.pldm_type = PLDM_PLATFORM;
1098 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1099
1100 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1101 if (rc != PLDM_SUCCESS) {
1102 return rc;
1103 }
1104
1105 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301106 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301107 request->format_version = format_version;
1108 request->tid = tid;
1109 request->event_class = event_class;
1110 memcpy(request->event_data, event_data, event_data_length);
1111
1112 return PLDM_SUCCESS;
1113}
1114
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301115LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301116int decode_platform_event_message_resp(const struct pldm_msg *msg,
1117 size_t payload_length,
1118 uint8_t *completion_code,
1119 uint8_t *platform_event_status)
1120{
Andrew Jefferye5011772023-04-13 12:06:22 +09301121 struct pldm_msgbuf _buf;
1122 struct pldm_msgbuf *buf = &_buf;
1123 int rc;
1124
Andrew Jeffery9c766792022-08-10 23:12:49 +09301125 if (msg == NULL || completion_code == NULL ||
1126 platform_event_status == NULL) {
1127 return PLDM_ERROR_INVALID_DATA;
1128 }
1129
Andrew Jefferye5011772023-04-13 12:06:22 +09301130 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1131 msg->payload, payload_length);
1132 if (rc) {
1133 return rc;
1134 }
1135
1136 rc = pldm_msgbuf_extract(buf, completion_code);
1137 if (rc) {
1138 return rc;
1139 }
1140
Andrew Jeffery9c766792022-08-10 23:12:49 +09301141 if (PLDM_SUCCESS != *completion_code) {
1142 return PLDM_SUCCESS;
1143 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301144
Andrew Jefferye5011772023-04-13 12:06:22 +09301145 rc = pldm_msgbuf_extract(buf, platform_event_status);
1146 if (rc) {
1147 return rc;
1148 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301149
1150 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1151 return PLDM_ERROR_INVALID_DATA;
1152 }
1153
Andrew Jefferye5011772023-04-13 12:06:22 +09301154 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301155}
1156
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301157LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301158int encode_event_message_buffer_size_req(uint8_t instance_id,
1159 uint16_t event_receiver_max_buffer_size,
1160 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001161{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301162 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001163 header.msg_type = PLDM_REQUEST;
1164 header.instance = instance_id;
1165 header.pldm_type = PLDM_PLATFORM;
1166 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1167
1168 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1169 if (rc != PLDM_SUCCESS) {
1170 return rc;
1171 }
1172
1173 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301174 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001175 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301176 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001177
1178 return PLDM_SUCCESS;
1179}
1180
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301181LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001182int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1183 size_t payload_length,
1184 uint8_t *completion_code,
1185 uint16_t *terminus_max_buffer_size)
1186{
Andrew Jeffery11126902023-04-13 12:12:10 +09301187 struct pldm_msgbuf _buf;
1188 struct pldm_msgbuf *buf = &_buf;
1189 int rc;
1190
Dung Caod6ae8982022-11-02 10:00:10 +07001191 if (msg == NULL || completion_code == NULL ||
1192 terminus_max_buffer_size == NULL) {
1193 return PLDM_ERROR_INVALID_DATA;
1194 }
1195
Andrew Jeffery11126902023-04-13 12:12:10 +09301196 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1197 msg->payload, payload_length);
1198 if (rc) {
1199 return rc;
1200 }
1201
1202 rc = pldm_msgbuf_extract(buf, completion_code);
1203 if (rc) {
1204 return rc;
1205 }
1206
Dung Caod6ae8982022-11-02 10:00:10 +07001207 if (PLDM_SUCCESS != *completion_code) {
1208 return PLDM_SUCCESS;
1209 }
Dung Caod6ae8982022-11-02 10:00:10 +07001210
Andrew Jeffery11126902023-04-13 12:12:10 +09301211 pldm_msgbuf_extract(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001212
Andrew Jeffery11126902023-04-13 12:12:10 +09301213 return pldm_msgbuf_destroy_consumed(buf);
Dung Caod6ae8982022-11-02 10:00:10 +07001214}
1215
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301216LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001217int encode_event_message_supported_req(uint8_t instance_id,
1218 uint8_t format_version,
1219 struct pldm_msg *msg)
1220{
1221 if (format_version != 1) {
1222 return PLDM_ERROR_INVALID_DATA;
1223 }
1224
1225 if (msg == NULL) {
1226 return PLDM_ERROR_INVALID_DATA;
1227 }
1228
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301229 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001230 header.msg_type = PLDM_REQUEST;
1231 header.instance = instance_id;
1232 header.pldm_type = PLDM_PLATFORM;
1233 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1234
1235 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1236 if (rc != PLDM_SUCCESS) {
1237 return rc;
1238 }
1239
1240 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301241 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001242 request->format_version = format_version;
1243
1244 return PLDM_SUCCESS;
1245}
1246
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301247LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301248int decode_event_message_supported_resp(const struct pldm_msg *msg,
1249 size_t payload_length,
1250 uint8_t *completion_code,
1251 uint8_t *synchrony_config,
1252 bitfield8_t *synchrony_config_support,
1253 uint8_t *number_event_class_returned,
1254 uint8_t *event_class,
1255 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001256{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301257 struct pldm_msgbuf _buf;
1258 struct pldm_msgbuf *buf = &_buf;
1259 int i;
1260 int rc;
1261
Dung Cao1bf8c872022-11-29 05:32:58 +07001262 if (msg == NULL || completion_code == NULL ||
1263 synchrony_config == NULL || synchrony_config_support == NULL ||
1264 number_event_class_returned == NULL || event_class == NULL) {
1265 return PLDM_ERROR_INVALID_DATA;
1266 }
1267
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301268 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1269 msg->payload, payload_length);
1270 if (rc) {
1271 return rc;
1272 }
1273
1274 rc = pldm_msgbuf_extract(buf, completion_code);
1275 if (rc) {
1276 return rc;
1277 }
1278
Dung Cao1bf8c872022-11-29 05:32:58 +07001279 if (PLDM_SUCCESS != *completion_code) {
1280 return PLDM_SUCCESS;
1281 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301282
1283 rc = pldm_msgbuf_extract(buf, synchrony_config);
1284 if (rc) {
1285 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001286 }
1287
Dung Cao1bf8c872022-11-29 05:32:58 +07001288 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1289 return PLDM_ERROR_INVALID_DATA;
1290 }
1291
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301292 pldm_msgbuf_extract(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001293
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301294 rc = pldm_msgbuf_extract(buf, number_event_class_returned);
1295 if (rc) {
1296 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001297 }
1298
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301299 if (*number_event_class_returned == 0) {
1300 return pldm_msgbuf_destroy(buf);
1301 }
1302
1303 if (event_class_count < *number_event_class_returned) {
1304 return PLDM_ERROR_INVALID_LENGTH;
1305 }
1306
1307 for (i = 0; i < *number_event_class_returned; i++) {
1308 pldm_msgbuf_extract(buf, &event_class[i]);
1309 }
1310
1311 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao1bf8c872022-11-29 05:32:58 +07001312}
1313
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301314LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301315int decode_sensor_event_data(const uint8_t *event_data,
1316 size_t event_data_length, uint16_t *sensor_id,
1317 uint8_t *sensor_event_class_type,
1318 size_t *event_class_data_offset)
1319{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301320 struct pldm_msgbuf _buf;
1321 struct pldm_msgbuf *buf = &_buf;
1322 int rc;
1323
1324 rc = pldm_msgbuf_init(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1325 event_data, event_data_length);
1326 if (rc) {
1327 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301328 }
1329
1330 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301331 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301332
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301333 pldm_msgbuf_extract(buf, sensor_id);
1334 rc = pldm_msgbuf_extract(buf, sensor_event_class_type);
1335 if (rc) {
1336 return rc;
1337 }
1338
1339 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301340 if (event_class_data_length !=
1341 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1342 return PLDM_ERROR_INVALID_LENGTH;
1343 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301344 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301345 if (event_class_data_length !=
1346 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1347 return PLDM_ERROR_INVALID_LENGTH;
1348 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301349 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301350 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301351 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301352 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301353 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301354 return PLDM_ERROR_INVALID_LENGTH;
1355 }
1356 } else {
1357 return PLDM_ERROR_INVALID_DATA;
1358 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301359
Andrew Jeffery9c766792022-08-10 23:12:49 +09301360 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301361 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301362
1363 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301364}
1365
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301366LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301367int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1368 uint8_t *present_op_state, uint8_t *previous_op_state)
1369{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301370 struct pldm_msgbuf _buf;
1371 struct pldm_msgbuf *buf = &_buf;
1372 int rc;
1373
1374 if (present_op_state == NULL || previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301375 return PLDM_ERROR_INVALID_DATA;
1376 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301377
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301378 rc = pldm_msgbuf_init(buf,
1379 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH,
1380 sensor_data, sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301381 if (rc) {
1382 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301383 }
1384
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301385 pldm_msgbuf_extract(buf, present_op_state);
1386 pldm_msgbuf_extract(buf, previous_op_state);
1387
1388 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301389}
1390
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301391LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301392int decode_state_sensor_data(const uint8_t *sensor_data,
1393 size_t sensor_data_length, uint8_t *sensor_offset,
1394 uint8_t *event_state,
1395 uint8_t *previous_event_state)
1396{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301397 struct pldm_msgbuf _buf;
1398 struct pldm_msgbuf *buf = &_buf;
1399 int rc;
1400
1401 if (sensor_offset == NULL || event_state == NULL ||
1402 previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301403 return PLDM_ERROR_INVALID_DATA;
1404 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301405
1406 rc = pldm_msgbuf_init(buf,
1407 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1408 sensor_data, sensor_data_length);
1409 if (rc) {
1410 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301411 }
1412
Andrew Jeffery422790b2023-04-13 15:03:47 +09301413 pldm_msgbuf_extract(buf, sensor_offset);
1414 pldm_msgbuf_extract(buf, event_state);
1415 pldm_msgbuf_extract(buf, previous_event_state);
1416
1417 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301418}
1419
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301420LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301421int decode_numeric_sensor_data(const uint8_t *sensor_data,
1422 size_t sensor_data_length, uint8_t *event_state,
1423 uint8_t *previous_event_state,
1424 uint8_t *sensor_data_size,
1425 uint32_t *present_reading)
1426{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301427 struct pldm_msgbuf _buf;
1428 struct pldm_msgbuf *buf = &_buf;
1429 int rc;
1430
1431 if (sensor_data_size == NULL || event_state == NULL ||
1432 previous_event_state == NULL || present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301433 return PLDM_ERROR_INVALID_DATA;
1434 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301435
1436 if (sensor_data_length >
1437 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301438 return PLDM_ERROR_INVALID_LENGTH;
1439 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301440
Andrew Jeffery155317e2023-04-13 18:36:51 +09301441 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301442 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1443 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301444 if (rc) {
1445 return rc;
1446 }
1447
1448 pldm_msgbuf_extract(buf, event_state);
1449 pldm_msgbuf_extract(buf, previous_event_state);
1450 rc = pldm_msgbuf_extract(buf, sensor_data_size);
1451 if (rc) {
1452 return rc;
1453 }
1454
1455 /*
1456 * The implementation below is bonkers, but it's because the function
1457 * prototype is bonkers. The `present_reading` argument should have been
1458 * a tagged union.
1459 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301460 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301461 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1462 uint8_t val;
1463 if (!pldm_msgbuf_extract(buf, &val)) {
1464 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301465 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301466 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301467 }
1468 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1469 int8_t val;
1470 if (!pldm_msgbuf_extract(buf, &val)) {
1471 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301472 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301473 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301474 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301475 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301476 uint16_t val;
1477 if (!pldm_msgbuf_extract(buf, &val)) {
1478 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301479 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301480 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301481 }
1482 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301483 int16_t val;
1484 if (!pldm_msgbuf_extract(buf, &val)) {
1485 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301486 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301487 break;
1488 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301489 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1490 uint32_t val;
1491 if (!pldm_msgbuf_extract(buf, &val)) {
1492 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301493 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301494 break;
1495 }
1496 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1497 int32_t val;
1498 if (!pldm_msgbuf_extract(buf, &val)) {
1499 *present_reading = (uint32_t)val;
1500 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301501 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301502 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301503 default:
1504 return PLDM_ERROR_INVALID_DATA;
1505 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301506
1507 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301508}
1509
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301510#define PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE 69
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301511LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301512int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301513 const void *pdr_data, size_t pdr_data_length,
1514 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301515{
1516 struct pldm_msgbuf _buf;
1517 struct pldm_msgbuf *buf = &_buf;
1518 int rc;
1519
1520 rc = pldm_msgbuf_init(buf, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1521 pdr_data, pdr_data_length);
1522 if (rc) {
1523 return rc;
1524 }
1525
1526 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1527 if (rc) {
1528 return rc;
1529 }
1530
1531 rc = pldm_platform_pdr_hdr_validate(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301532 &pdr_value->hdr, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1533 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301534 if (rc) {
1535 return rc;
1536 }
1537
1538 pldm_msgbuf_extract(buf, &pdr_value->terminus_handle);
1539 pldm_msgbuf_extract(buf, &pdr_value->sensor_id);
1540 pldm_msgbuf_extract(buf, &pdr_value->entity_type);
1541 pldm_msgbuf_extract(buf, &pdr_value->entity_instance_num);
1542 pldm_msgbuf_extract(buf, &pdr_value->container_id);
1543 pldm_msgbuf_extract(buf, &pdr_value->sensor_init);
1544 pldm_msgbuf_extract(buf, &pdr_value->sensor_auxiliary_names_pdr);
1545 pldm_msgbuf_extract(buf, &pdr_value->base_unit);
1546 pldm_msgbuf_extract(buf, &pdr_value->unit_modifier);
1547 pldm_msgbuf_extract(buf, &pdr_value->rate_unit);
1548 pldm_msgbuf_extract(buf, &pdr_value->base_oem_unit_handle);
1549 pldm_msgbuf_extract(buf, &pdr_value->aux_unit);
1550 pldm_msgbuf_extract(buf, &pdr_value->aux_unit_modifier);
1551 pldm_msgbuf_extract(buf, &pdr_value->aux_rate_unit);
1552 pldm_msgbuf_extract(buf, &pdr_value->rel);
1553 pldm_msgbuf_extract(buf, &pdr_value->aux_oem_unit_handle);
1554 pldm_msgbuf_extract(buf, &pdr_value->is_linear);
1555
1556 rc = pldm_msgbuf_extract(buf, &pdr_value->sensor_data_size);
1557 if (rc) {
1558 return rc;
1559 }
1560 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1561 return PLDM_ERROR_INVALID_DATA;
1562 }
1563
1564 pldm_msgbuf_extract(buf, &pdr_value->resolution);
1565 pldm_msgbuf_extract(buf, &pdr_value->offset);
1566 pldm_msgbuf_extract(buf, &pdr_value->accuracy);
1567 pldm_msgbuf_extract(buf, &pdr_value->plus_tolerance);
1568 pldm_msgbuf_extract(buf, &pdr_value->minus_tolerance);
1569 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1570 &pdr_value->hysteresis);
1571 pldm_msgbuf_extract(buf, &pdr_value->supported_thresholds.byte);
1572 pldm_msgbuf_extract(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301573 buf, &pdr_value->threshold_and_hysteresis_volatility.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301574 pldm_msgbuf_extract(buf, &pdr_value->state_transition_interval);
1575 pldm_msgbuf_extract(buf, &pdr_value->update_interval);
1576 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1577 &pdr_value->max_readable);
1578 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1579 &pdr_value->min_readable);
1580
1581 rc = pldm_msgbuf_extract(buf, &pdr_value->range_field_format);
1582 if (rc) {
1583 return rc;
1584 }
1585 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1586 return PLDM_ERROR_INVALID_DATA;
1587 }
1588
1589 pldm_msgbuf_extract(buf, &pdr_value->range_field_support.byte);
1590 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301591 buf, pdr_value->range_field_format, &pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301592 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301593 buf, pdr_value->range_field_format, &pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301594 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301595 buf, pdr_value->range_field_format, &pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301596 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301597 buf, pdr_value->range_field_format, &pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301598 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301599 buf, pdr_value->range_field_format, &pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301600 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301601 buf, pdr_value->range_field_format, &pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301602 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301603 buf, pdr_value->range_field_format, &pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301604 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301605 buf, pdr_value->range_field_format, &pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301606 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301607 buf, pdr_value->range_field_format, &pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301608
1609 return pldm_msgbuf_destroy(buf);
1610}
1611
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301612LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301613int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1614 uint16_t effecter_id,
1615 struct pldm_msg *msg)
1616{
1617 if (msg == NULL) {
1618 return PLDM_ERROR_INVALID_DATA;
1619 }
1620
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301621 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301622 header.msg_type = PLDM_REQUEST;
1623 header.instance = instance_id;
1624 header.pldm_type = PLDM_PLATFORM;
1625 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1626
1627 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1628 if (rc != PLDM_SUCCESS) {
1629 return rc;
1630 }
1631
1632 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301633 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301634 request->effecter_id = htole16(effecter_id);
1635
1636 return PLDM_SUCCESS;
1637}
1638
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301639LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301640int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301641 uint8_t instance_id, uint8_t completion_code,
1642 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1643 const uint8_t *pending_value, const uint8_t *present_value,
1644 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301645{
1646 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1647 return PLDM_ERROR_INVALID_DATA;
1648 }
1649
1650 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1651 return PLDM_ERROR_INVALID_DATA;
1652 }
1653
1654 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1655 return PLDM_ERROR_INVALID_DATA;
1656 }
1657
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301658 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301659 header.msg_type = PLDM_RESPONSE;
1660 header.instance = instance_id;
1661 header.pldm_type = PLDM_PLATFORM;
1662 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1663
1664 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1665 if (rc != PLDM_SUCCESS) {
1666 return rc;
1667 }
1668
1669 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301670 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301671
1672 response->completion_code = completion_code;
1673 response->effecter_data_size = effecter_data_size;
1674 response->effecter_oper_state = effecter_oper_state;
1675
1676 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1677 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1678 if (payload_length !=
1679 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1680 return PLDM_ERROR_INVALID_LENGTH;
1681 }
1682 response->pending_and_present_values[0] = *pending_value;
1683 response->pending_and_present_values[1] = *present_value;
1684
1685 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1686 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1687 if (payload_length !=
1688 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1689 return PLDM_ERROR_INVALID_LENGTH;
1690 }
1691 uint16_t val_pending = *(uint16_t *)pending_value;
1692 val_pending = htole16(val_pending);
1693 memcpy(response->pending_and_present_values, &val_pending,
1694 sizeof(uint16_t));
1695 uint16_t val_present = *(uint16_t *)present_value;
1696 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301697 memcpy((response->pending_and_present_values +
1698 sizeof(uint16_t)),
1699 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301700
1701 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1702 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1703 if (payload_length !=
1704 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1705 return PLDM_ERROR_INVALID_LENGTH;
1706 }
1707 uint32_t val_pending = *(uint32_t *)pending_value;
1708 val_pending = htole32(val_pending);
1709 memcpy(response->pending_and_present_values, &val_pending,
1710 sizeof(uint32_t));
1711 uint32_t val_present = *(uint32_t *)present_value;
1712 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301713 memcpy((response->pending_and_present_values +
1714 sizeof(uint32_t)),
1715 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301716 }
1717 return PLDM_SUCCESS;
1718}
1719
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301720LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301721int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1722 size_t payload_length,
1723 uint16_t *effecter_id)
1724{
Andrew Jefferydd265822023-04-13 22:42:44 +09301725 struct pldm_msgbuf _buf;
1726 struct pldm_msgbuf *buf = &_buf;
1727 int rc;
1728
Andrew Jeffery9c766792022-08-10 23:12:49 +09301729 if (msg == NULL || effecter_id == NULL) {
1730 return PLDM_ERROR_INVALID_DATA;
1731 }
1732
Andrew Jefferydd265822023-04-13 22:42:44 +09301733 rc = pldm_msgbuf_init(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
1734 msg->payload, payload_length);
1735 if (rc) {
1736 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301737 }
1738
Andrew Jefferydd265822023-04-13 22:42:44 +09301739 pldm_msgbuf_extract(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301740
Andrew Jefferydd265822023-04-13 22:42:44 +09301741 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301742}
1743
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301744LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301745int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
1746 size_t payload_length,
1747 uint8_t *completion_code,
1748 uint8_t *effecter_data_size,
1749 uint8_t *effecter_oper_state,
1750 uint8_t *pending_value,
1751 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301752{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301753 struct pldm_msgbuf _buf;
1754 struct pldm_msgbuf *buf = &_buf;
1755 int rc;
1756
Andrew Jeffery9c766792022-08-10 23:12:49 +09301757 if (msg == NULL || effecter_data_size == NULL ||
1758 effecter_oper_state == NULL || pending_value == NULL ||
1759 present_value == NULL) {
1760 return PLDM_ERROR_INVALID_DATA;
1761 }
1762
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301763 rc = pldm_msgbuf_init(buf,
1764 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
1765 msg->payload, payload_length);
1766 if (rc) {
1767 return rc;
1768 }
1769
1770 rc = pldm_msgbuf_extract(buf, completion_code);
1771 if (rc) {
1772 return rc;
1773 }
1774
Andrew Jeffery9c766792022-08-10 23:12:49 +09301775 if (PLDM_SUCCESS != *completion_code) {
1776 return PLDM_SUCCESS;
1777 }
1778
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301779 rc = pldm_msgbuf_extract(buf, effecter_data_size);
1780 if (rc) {
1781 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301782 }
1783
Andrew Jeffery9c766792022-08-10 23:12:49 +09301784 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1785 return PLDM_ERROR_INVALID_DATA;
1786 }
1787
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301788 rc = pldm_msgbuf_extract(buf, effecter_oper_state);
1789 if (rc) {
1790 return rc;
1791 }
1792
Andrew Jeffery9c766792022-08-10 23:12:49 +09301793 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1794 return PLDM_ERROR_INVALID_DATA;
1795 }
1796
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301797 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1798 pending_value);
1799 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1800 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301801
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301802 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301803}
1804
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301805LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301806int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301807 uint8_t event_data_format, uint8_t number_of_change_records,
1808 const uint8_t *event_data_operations,
1809 const uint8_t *numbers_of_change_entries,
1810 const uint32_t *const *change_entries,
1811 struct pldm_pdr_repository_chg_event_data *event_data,
1812 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301813{
1814 if (event_data_operations == NULL ||
1815 numbers_of_change_entries == NULL || change_entries == NULL) {
1816 return PLDM_ERROR_INVALID_DATA;
1817 }
1818
1819 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301820 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301821
1822 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301823 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301824 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301825 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301826
1827 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301828 expected_size += sizeof(*change_entries[0]) *
1829 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301830 }
1831
1832 *actual_change_records_size = expected_size;
1833
1834 if (event_data == NULL) {
1835 return PLDM_SUCCESS;
1836 }
1837
1838 if (max_change_records_size < expected_size) {
1839 return PLDM_ERROR_INVALID_LENGTH;
1840 }
1841
1842 event_data->event_data_format = event_data_format;
1843 event_data->number_of_change_records = number_of_change_records;
1844
1845 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301846 (struct pldm_pdr_repository_change_record_data *)
1847 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301848
1849 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1850 record_data->event_data_operation = event_data_operations[i];
1851 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301852 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301853
1854 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1855 ++j) {
1856 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301857 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301858 }
1859
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301860 record_data =
1861 (struct pldm_pdr_repository_change_record_data
1862 *)(record_data->change_entry +
1863 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301864 }
1865
1866 return PLDM_SUCCESS;
1867}
1868
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301869LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301870int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1871 size_t event_data_size,
1872 uint8_t *event_data_format,
1873 uint8_t *number_of_change_records,
1874 size_t *change_record_data_offset)
1875{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301876 struct pldm_msgbuf _buf;
1877 struct pldm_msgbuf *buf = &_buf;
1878 int rc;
1879
1880 if (event_data_format == NULL || number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301881 change_record_data_offset == NULL) {
1882 return PLDM_ERROR_INVALID_DATA;
1883 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301884
1885 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
1886 event_data, event_data_size);
1887 if (rc) {
1888 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301889 }
1890
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301891 pldm_msgbuf_extract(buf, event_data_format);
1892 pldm_msgbuf_extract(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301893
Andrew Jeffery9c766792022-08-10 23:12:49 +09301894 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301895 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301896
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301897 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301898}
1899
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301900LIBPLDM_ABI_TESTING
Dung Cao7c250342022-11-16 22:40:37 +07001901int decode_pldm_message_poll_event_data(const uint8_t *event_data,
1902 size_t event_data_length,
1903 uint8_t *format_version,
1904 uint16_t *event_id,
1905 uint32_t *data_transfer_handle)
1906{
1907 struct pldm_msgbuf _buf;
1908 struct pldm_msgbuf *buf = &_buf;
1909 int rc;
1910
1911 if (event_data == NULL || format_version == NULL || event_id == NULL ||
1912 data_transfer_handle == NULL) {
1913 return PLDM_ERROR_INVALID_DATA;
1914 }
1915
1916 rc = pldm_msgbuf_init(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
1917 event_data_length);
1918 if (rc) {
1919 return rc;
1920 }
1921
1922 pldm_msgbuf_extract(buf, format_version);
1923 rc = pldm_msgbuf_extract(buf, event_id);
1924 if (rc) {
1925 return rc;
1926 }
1927
1928 if (*event_id == 0x0000 || *event_id == 0xffff) {
1929 return PLDM_ERROR_INVALID_DATA;
1930 }
1931
1932 pldm_msgbuf_extract(buf, data_transfer_handle);
1933
1934 return pldm_msgbuf_destroy_consumed(buf);
1935}
1936
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301937LIBPLDM_ABI_TESTING
Dung Cao7c250342022-11-16 22:40:37 +07001938int encode_pldm_message_poll_event_data(uint8_t format_version,
1939 uint16_t event_id,
1940 uint32_t data_transfer_handle,
1941 uint8_t *event_data,
1942 size_t event_data_length)
1943{
1944 struct pldm_msgbuf _buf;
1945 struct pldm_msgbuf *buf = &_buf;
1946 int rc;
1947
1948 if (event_data == NULL) {
1949 return PLDM_ERROR_INVALID_DATA;
1950 }
1951
1952 if (event_id == 0x0000 || event_id == 0xffff) {
1953 return PLDM_ERROR_INVALID_DATA;
1954 }
1955
1956 rc = pldm_msgbuf_init(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
1957 event_data_length);
1958 if (rc) {
1959 return rc;
1960 }
1961 pldm_msgbuf_insert(buf, format_version);
1962 pldm_msgbuf_insert(buf, event_id);
1963 pldm_msgbuf_insert(buf, data_transfer_handle);
1964
1965 return pldm_msgbuf_destroy(buf);
1966}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301967
1968LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301969int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301970 const uint8_t *change_record_data, size_t change_record_data_size,
1971 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1972 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301973{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301974 struct pldm_msgbuf _buf;
1975 struct pldm_msgbuf *buf = &_buf;
1976 int rc;
1977
1978 if (event_data_operation == NULL || number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301979 change_entry_data_offset == NULL) {
1980 return PLDM_ERROR_INVALID_DATA;
1981 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301982
1983 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
1984 change_record_data, change_record_data_size);
1985 if (rc) {
1986 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301987 }
1988
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301989 pldm_msgbuf_extract(buf, event_data_operation);
1990 pldm_msgbuf_extract(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301991
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301992 *change_entry_data_offset = sizeof(*event_data_operation) +
1993 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301994
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301995 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301996}
1997
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301998LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301999int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2000 uint8_t rearm_event_state,
2001 struct pldm_msg *msg)
2002{
2003 if (msg == NULL) {
2004 return PLDM_ERROR_INVALID_DATA;
2005 }
2006
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302007 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302008 header.msg_type = PLDM_REQUEST;
2009 header.instance = instance_id;
2010 header.pldm_type = PLDM_PLATFORM;
2011 header.command = PLDM_GET_SENSOR_READING;
2012
2013 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2014 if (rc != PLDM_SUCCESS) {
2015 return rc;
2016 }
2017
2018 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302019 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302020
2021 request->sensor_id = htole16(sensor_id);
2022 request->rearm_event_state = rearm_event_state;
2023
2024 return PLDM_SUCCESS;
2025}
2026
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302027LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302028int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302029 const struct pldm_msg *msg, size_t payload_length,
2030 uint8_t *completion_code, uint8_t *sensor_data_size,
2031 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2032 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2033 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302034{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302035 struct pldm_msgbuf _buf;
2036 struct pldm_msgbuf *buf = &_buf;
2037 int rc;
2038
Andrew Jeffery9c766792022-08-10 23:12:49 +09302039 if (msg == NULL || completion_code == NULL ||
2040 sensor_data_size == NULL || sensor_operational_state == NULL ||
2041 sensor_event_message_enable == NULL || present_state == NULL ||
2042 previous_state == NULL || event_state == NULL ||
2043 present_reading == NULL) {
2044 return PLDM_ERROR_INVALID_DATA;
2045 }
2046
Andrew Jeffery840b1402023-04-13 23:54:44 +09302047 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2048 msg->payload, payload_length);
2049 if (rc) {
2050 return rc;
2051 }
2052
2053 rc = pldm_msgbuf_extract(buf, completion_code);
2054 if (rc) {
2055 return rc;
2056 }
2057
Andrew Jeffery9c766792022-08-10 23:12:49 +09302058 if (PLDM_SUCCESS != *completion_code) {
2059 return PLDM_SUCCESS;
2060 }
2061
Andrew Jeffery840b1402023-04-13 23:54:44 +09302062 rc = pldm_msgbuf_extract(buf, sensor_data_size);
2063 if (rc) {
2064 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302065 }
2066
Andrew Jeffery840b1402023-04-13 23:54:44 +09302067 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302068 return PLDM_ERROR_INVALID_DATA;
2069 }
2070
Andrew Jeffery840b1402023-04-13 23:54:44 +09302071 pldm_msgbuf_extract(buf, sensor_operational_state);
2072 pldm_msgbuf_extract(buf, sensor_event_message_enable);
2073 pldm_msgbuf_extract(buf, present_state);
2074 pldm_msgbuf_extract(buf, previous_state);
2075 pldm_msgbuf_extract(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302076
Andrew Jeffery840b1402023-04-13 23:54:44 +09302077 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2078 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302079
Andrew Jeffery840b1402023-04-13 23:54:44 +09302080 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302081}
2082
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302083LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302084int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2085 uint8_t sensor_data_size,
2086 uint8_t sensor_operational_state,
2087 uint8_t sensor_event_message_enable,
2088 uint8_t present_state,
2089 uint8_t previous_state, uint8_t event_state,
2090 const uint8_t *present_reading,
2091 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302092{
2093 if (msg == NULL || present_reading == NULL) {
2094 return PLDM_ERROR_INVALID_DATA;
2095 }
2096
2097 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2098 return PLDM_ERROR_INVALID_DATA;
2099 }
2100
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302101 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302102 header.msg_type = PLDM_RESPONSE;
2103 header.instance = instance_id;
2104 header.pldm_type = PLDM_PLATFORM;
2105 header.command = PLDM_GET_SENSOR_READING;
2106
2107 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2108 if (rc != PLDM_SUCCESS) {
2109 return rc;
2110 }
2111
2112 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302113 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302114
2115 response->completion_code = completion_code;
2116 response->sensor_data_size = sensor_data_size;
2117 response->sensor_operational_state = sensor_operational_state;
2118 response->sensor_event_message_enable = sensor_event_message_enable;
2119 response->present_state = present_state;
2120 response->previous_state = previous_state;
2121 response->event_state = event_state;
2122
2123 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2124 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2125 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2126 return PLDM_ERROR_INVALID_LENGTH;
2127 }
2128 response->present_reading[0] = *present_reading;
2129
2130 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2131 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2132 if (payload_length !=
2133 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2134 return PLDM_ERROR_INVALID_LENGTH;
2135 }
2136 uint16_t val = *(uint16_t *)present_reading;
2137 val = htole16(val);
2138 memcpy(response->present_reading, &val, 2);
2139
2140 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2141 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2142 if (payload_length !=
2143 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2144 return PLDM_ERROR_INVALID_LENGTH;
2145 }
2146 uint32_t val = *(uint32_t *)present_reading;
2147 val = htole32(val);
2148 memcpy(response->present_reading, &val, 4);
2149 }
2150
2151 return PLDM_SUCCESS;
2152}
2153
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302154LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302155int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2156 size_t payload_length, uint16_t *sensor_id,
2157 uint8_t *rearm_event_state)
2158{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302159 struct pldm_msgbuf _buf;
2160 struct pldm_msgbuf *buf = &_buf;
2161 int rc;
2162
Andrew Jeffery9c766792022-08-10 23:12:49 +09302163 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2164 return PLDM_ERROR_INVALID_DATA;
2165 }
2166
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302167 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2168 msg->payload, payload_length);
2169 if (rc) {
2170 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302171 }
2172
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302173 pldm_msgbuf_extract(buf, sensor_id);
2174 pldm_msgbuf_extract(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302175
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302176 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302177}
2178
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302179LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302180int encode_set_event_receiver_req(uint8_t instance_id,
2181 uint8_t event_message_global_enable,
2182 uint8_t transport_protocol_type,
2183 uint8_t event_receiver_address_info,
2184 uint16_t heartbeat_timer,
2185 struct pldm_msg *msg)
2186{
2187 if (msg == NULL) {
2188 return PLDM_ERROR_INVALID_DATA;
2189 }
2190
2191 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2192 return PLDM_ERROR_INVALID_DATA;
2193 }
2194
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302195 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302196 header.msg_type = PLDM_REQUEST;
2197 header.instance = instance_id;
2198 header.pldm_type = PLDM_PLATFORM;
2199 header.command = PLDM_SET_EVENT_RECEIVER;
2200
2201 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2202 if (rc != PLDM_SUCCESS) {
2203 return rc;
2204 }
2205
2206 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302207 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302208 request->event_message_global_enable = event_message_global_enable;
2209
2210 request->transport_protocol_type = transport_protocol_type;
2211 request->event_receiver_address_info = event_receiver_address_info;
2212
2213 if (event_message_global_enable ==
2214 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2215 if (heartbeat_timer == 0) {
2216 return PLDM_ERROR_INVALID_DATA;
2217 }
2218 request->heartbeat_timer = htole16(heartbeat_timer);
2219 }
2220
2221 return PLDM_SUCCESS;
2222}
2223
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302224LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302225int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2226 size_t payload_length,
2227 uint8_t *completion_code)
2228{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302229 struct pldm_msgbuf _buf;
2230 struct pldm_msgbuf *buf = &_buf;
2231 int rc;
2232
Andrew Jeffery9c766792022-08-10 23:12:49 +09302233 if (msg == NULL || completion_code == NULL) {
2234 return PLDM_ERROR_INVALID_DATA;
2235 }
2236
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302237 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2238 msg->payload, payload_length);
2239 if (rc) {
2240 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302241 }
2242
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302243 pldm_msgbuf_extract(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302244
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302245 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302246}
2247
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302248LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302249int decode_set_event_receiver_req(const struct pldm_msg *msg,
2250 size_t payload_length,
2251 uint8_t *event_message_global_enable,
2252 uint8_t *transport_protocol_type,
2253 uint8_t *event_receiver_address_info,
2254 uint16_t *heartbeat_timer)
2255
2256{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302257 struct pldm_msgbuf _buf;
2258 struct pldm_msgbuf *buf = &_buf;
2259 int rc;
2260
Andrew Jeffery9c766792022-08-10 23:12:49 +09302261 if (msg == NULL || event_message_global_enable == NULL ||
2262 transport_protocol_type == NULL ||
2263 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2264 return PLDM_ERROR_INVALID_DATA;
2265 }
2266
Andrew Jeffery9667f582023-04-14 00:39:21 +09302267 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2268 msg->payload, payload_length);
2269 if (rc) {
2270 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302271 }
2272
Andrew Jeffery9667f582023-04-14 00:39:21 +09302273 pldm_msgbuf_extract(buf, event_message_global_enable);
2274 pldm_msgbuf_extract(buf, transport_protocol_type);
2275 pldm_msgbuf_extract(buf, event_receiver_address_info);
2276 pldm_msgbuf_extract(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302277
Andrew Jeffery9667f582023-04-14 00:39:21 +09302278 rc = pldm_msgbuf_destroy(buf);
2279 if (rc) {
2280 return rc;
2281 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302282
Andrew Jeffery9c766792022-08-10 23:12:49 +09302283 if ((*event_message_global_enable ==
2284 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2285 (*heartbeat_timer == 0)) {
2286 return PLDM_ERROR_INVALID_DATA;
2287 }
2288
Andrew Jeffery9c766792022-08-10 23:12:49 +09302289 return PLDM_SUCCESS;
2290}
2291
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302292LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302293int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2294 struct pldm_msg *msg)
2295
2296{
2297 if (msg == NULL) {
2298 return PLDM_ERROR_INVALID_DATA;
2299 }
2300
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302301 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302302 header.instance = instance_id;
2303 header.msg_type = PLDM_RESPONSE;
2304 header.pldm_type = PLDM_PLATFORM;
2305 header.command = PLDM_SET_EVENT_RECEIVER;
2306
2307 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2308 if (rc != PLDM_SUCCESS) {
2309 return rc;
2310 }
2311
2312 msg->payload[0] = completion_code;
2313
2314 return PLDM_SUCCESS;
2315}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002316
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302317LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002318int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2319 uint8_t format_version,
2320 uint8_t transfer_operation_flag,
2321 uint32_t data_transfer_handle,
2322 uint16_t event_id_to_acknowledge,
2323 struct pldm_msg *msg,
2324 size_t payload_length)
2325{
2326 struct pldm_msgbuf _buf;
2327 struct pldm_msgbuf *buf = &_buf;
2328 int rc;
2329
2330 if (msg == NULL) {
2331 return PLDM_ERROR_INVALID_DATA;
2332 }
2333
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302334 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002335 header.msg_type = PLDM_REQUEST;
2336 header.instance = instance_id;
2337 header.pldm_type = PLDM_PLATFORM;
2338 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2339
2340 rc = pack_pldm_header(&header, &(msg->hdr));
2341 if (rc != PLDM_SUCCESS) {
2342 return rc;
2343 }
2344
2345 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302346 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2347 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002348 if (rc) {
2349 return rc;
2350 }
2351
2352 pldm_msgbuf_insert(buf, format_version);
2353 pldm_msgbuf_insert(buf, transfer_operation_flag);
2354 pldm_msgbuf_insert(buf, data_transfer_handle);
2355 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2356
2357 return pldm_msgbuf_destroy(buf);
2358}
2359
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302360LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002361int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302362 const struct pldm_msg *msg, size_t payload_length,
2363 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2364 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2365 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2366 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002367{
2368 struct pldm_msgbuf _buf;
2369 struct pldm_msgbuf *buf = &_buf;
2370 int rc;
2371
2372 if (msg == NULL || completion_code == NULL || tid == NULL ||
2373 event_id == NULL || next_data_transfer_handle == NULL ||
2374 transfer_flag == NULL || event_class == NULL ||
2375 event_data_size == NULL || event_data == NULL ||
2376 event_data_integrity_checksum == NULL) {
2377 return PLDM_ERROR_INVALID_DATA;
2378 }
2379
2380 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302381 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2382 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002383 if (rc) {
2384 return rc;
2385 }
2386
2387 rc = pldm_msgbuf_extract(buf, completion_code);
2388 if (rc) {
2389 return rc;
2390 }
2391 if (PLDM_SUCCESS != *completion_code) {
2392 return *completion_code;
2393 }
2394
2395 pldm_msgbuf_extract(buf, tid);
2396 rc = pldm_msgbuf_extract(buf, event_id);
2397 if (rc) {
2398 return rc;
2399 }
2400 if ((*event_id == 0) || (*event_id == 0xffff)) {
2401 return PLDM_SUCCESS;
2402 }
2403
2404 pldm_msgbuf_extract(buf, next_data_transfer_handle);
2405 rc = pldm_msgbuf_extract(buf, transfer_flag);
2406 if (rc) {
2407 return rc;
2408 }
2409
2410 pldm_msgbuf_extract(buf, event_class);
2411 rc = pldm_msgbuf_extract(buf, event_data_size);
2412 if (rc) {
2413 return rc;
2414 }
2415 if (*event_data_size > payload_length) {
2416 return PLDM_ERROR_INVALID_DATA;
2417 }
2418
2419 if (*event_data_size > 0) {
2420 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2421 }
2422
2423 if (*transfer_flag == PLDM_END ||
2424 *transfer_flag == PLDM_START_AND_END) {
2425 pldm_msgbuf_extract(buf, event_data_integrity_checksum);
2426 }
2427
2428 return pldm_msgbuf_destroy_consumed(buf);
2429}