blob: 52caa53a648fb3a8514de60e0c13fc84965651f7 [file] [log] [blame]
Patrick Williams691668f2023-11-01 08:19:10 -05001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302#include "api.h"
3#include "compiler.h"
Tal Yacobif490a382024-05-31 09:57:36 +03004#include "dsp/base.h"
Andrew Jeffery7992eb82023-04-06 16:13:53 +09305#include "msgbuf.h"
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10306#include "msgbuf/platform.h"
7
8#include <libpldm/base.h>
9#include <libpldm/platform.h>
10#include <libpldm/pldm_types.h>
11
Andrew Jeffery9c766792022-08-10 23:12:49 +093012#include <endian.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053013#include <stdint.h>
Thu Nguyen159a98b2022-11-02 10:00:10 +070014#include <stdlib.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093015#include <string.h>
Thu Nguyendacfa352024-06-22 09:53:15 +000016#include <uchar.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093017
Andrew Jeffery7992eb82023-04-06 16:13:53 +093018static int pldm_platform_pdr_hdr_validate(struct pldm_value_pdr_hdr *ctx,
19 size_t lower, size_t upper)
20{
21 if (ctx->length + sizeof(*ctx) < lower) {
22 return PLDM_ERROR_INVALID_LENGTH;
23 }
24
25 if (ctx->length > upper) {
26 return PLDM_ERROR_INVALID_LENGTH;
27 }
28
29 return PLDM_SUCCESS;
30}
Andrew Jeffery9c766792022-08-10 23:12:49 +093031
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093032LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093033int encode_state_effecter_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093034 struct pldm_state_effecter_pdr *const effecter,
35 const size_t allocation_size,
36 const struct state_effecter_possible_states *const possible_states,
37 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093038{
39 // Encode possible states
40
41 size_t calculated_possible_states_size = 0;
42
43 {
44 char *states_ptr = (char *)possible_states;
45 char *const begin_states_ptr = states_ptr;
46
47 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
48 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093049 (struct state_effecter_possible_states *)
50 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093051
52 HTOLE16(states->state_set_id);
53
54 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093055 (sizeof(*states) - sizeof(states->states) +
56 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093057 }
58
59 calculated_possible_states_size = states_ptr - begin_states_ptr;
60 }
61
62 // Check lengths
63
64 if (possible_states_size != calculated_possible_states_size) {
65 *actual_size = 0;
66 return PLDM_ERROR;
67 }
68
69 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093070 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
71 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093072
73 if (allocation_size < *actual_size) {
74 *actual_size = 0;
75 return PLDM_ERROR_INVALID_LENGTH;
76 }
77
78 // Encode rest of PDR
79
80 effecter->hdr.version = 1;
81 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
82 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
83
84 memcpy(effecter->possible_states, possible_states,
85 possible_states_size);
86
87 // Convert effecter PDR body
88 HTOLE16(effecter->terminus_handle);
89 HTOLE16(effecter->effecter_id);
90 HTOLE16(effecter->entity_type);
91 HTOLE16(effecter->entity_instance);
92 HTOLE16(effecter->container_id);
93 HTOLE16(effecter->effecter_semantic_id);
94
95 // Convert header
96 HTOLE32(effecter->hdr.record_handle);
97 HTOLE16(effecter->hdr.record_change_num);
98 HTOLE16(effecter->hdr.length);
99
100 return PLDM_SUCCESS;
101}
102
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930103LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930104int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930105 struct pldm_state_sensor_pdr *const sensor,
106 const size_t allocation_size,
107 const struct state_sensor_possible_states *const possible_states,
108 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930109{
110 // Encode possible states
111
112 size_t calculated_possible_states_size = 0;
113
114 {
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930115 char *states_ptr = (char *)possible_states;
116 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930117
118 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
119 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930120 (struct state_sensor_possible_states *)
121 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930122
123 HTOLE16(states->state_set_id);
124
125 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930126 (sizeof(*states) - sizeof(states->states) +
127 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930128 }
129
130 calculated_possible_states_size = states_ptr - begin_states_ptr;
131 }
132
133 // Check lengths
134
135 if (possible_states_size != calculated_possible_states_size) {
136 *actual_size = 0;
137 return PLDM_ERROR;
138 }
139
140 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
141 possible_states_size - sizeof(sensor->possible_states));
142
143 if (allocation_size < *actual_size) {
144 *actual_size = 0;
145 return PLDM_ERROR_INVALID_LENGTH;
146 }
147
148 // Encode rest of PDR
149
150 sensor->hdr.version = 1;
151 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
152 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
153
154 memcpy(sensor->possible_states, possible_states, possible_states_size);
155
156 // Convert sensor PDR body
157 HTOLE16(sensor->terminus_handle);
158 HTOLE16(sensor->sensor_id);
159 HTOLE16(sensor->entity_type);
160 HTOLE16(sensor->entity_instance);
161 HTOLE16(sensor->container_id);
162
163 // Convert header
164 HTOLE32(sensor->hdr.record_handle);
165 HTOLE16(sensor->hdr.record_change_num);
166 HTOLE16(sensor->hdr.length);
167
168 return PLDM_SUCCESS;
169}
170
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930171LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930172int encode_set_state_effecter_states_resp(uint8_t instance_id,
173 uint8_t completion_code,
174 struct pldm_msg *msg)
175{
176 if (msg == NULL) {
177 return PLDM_ERROR_INVALID_DATA;
178 }
179
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930180 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930181 header.msg_type = PLDM_RESPONSE;
182 header.instance = instance_id;
183 header.pldm_type = PLDM_PLATFORM;
184 header.command = PLDM_SET_STATE_EFFECTER_STATES;
185
186 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
187 if (rc != PLDM_SUCCESS) {
188 return rc;
189 }
190
191 msg->payload[0] = completion_code;
192
193 return PLDM_SUCCESS;
194}
195
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930196LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930197int encode_set_state_effecter_states_req(uint8_t instance_id,
198 uint16_t effecter_id,
199 uint8_t comp_effecter_count,
200 set_effecter_state_field *field,
201 struct pldm_msg *msg)
202{
203 if (msg == NULL) {
204 return PLDM_ERROR_INVALID_DATA;
205 }
206
207 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
208 field == NULL) {
209 return PLDM_ERROR_INVALID_DATA;
210 }
211
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930212 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930213 header.msg_type = PLDM_REQUEST;
214 header.instance = instance_id;
215 header.pldm_type = PLDM_PLATFORM;
216 header.command = PLDM_SET_STATE_EFFECTER_STATES;
217
218 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
219 if (rc != PLDM_SUCCESS) {
220 return rc;
221 }
222
223 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930224 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930225 effecter_id = htole16(effecter_id);
226 request->effecter_id = effecter_id;
227 request->comp_effecter_count = comp_effecter_count;
228 memcpy(request->field, field,
229 (sizeof(set_effecter_state_field) * comp_effecter_count));
230
231 return PLDM_SUCCESS;
232}
233
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930234LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930235int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
236 size_t payload_length,
237 uint8_t *completion_code)
238{
239 if (msg == NULL || completion_code == NULL) {
240 return PLDM_ERROR_INVALID_DATA;
241 }
242
243 *completion_code = msg->payload[0];
244 if (PLDM_SUCCESS != *completion_code) {
245 return PLDM_SUCCESS;
246 }
247
248 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
249 return PLDM_ERROR_INVALID_LENGTH;
250 }
251
252 return PLDM_SUCCESS;
253}
254
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930255#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930256LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930257int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
258 size_t payload_length,
259 uint16_t *effecter_id,
260 uint8_t *comp_effecter_count,
261 set_effecter_state_field *field)
262{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930263 struct pldm_msgbuf _buf;
264 struct pldm_msgbuf *buf = &_buf;
265 int rc;
266 int i;
267
Andrew Jeffery9c766792022-08-10 23:12:49 +0930268 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
269 field == NULL) {
270 return PLDM_ERROR_INVALID_DATA;
271 }
272
273 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
274 return PLDM_ERROR_INVALID_LENGTH;
275 }
276
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930277 rc = pldm_msgbuf_init_errno(buf,
278 PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
279 msg->payload, payload_length);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930280 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930281 return pldm_xlate_errno(rc);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930282 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930283
Andrew Jeffery66c77232024-04-24 11:42:02 +0930284 pldm_msgbuf_extract_p(buf, effecter_id);
285 pldm_msgbuf_extract_p(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930286
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930287 if (*comp_effecter_count > 8) {
288 return PLDM_ERROR_INVALID_DATA;
289 }
290
291 for (i = 0; i < *comp_effecter_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930292 pldm_msgbuf_extract(buf, field[i].set_request);
293 pldm_msgbuf_extract(buf, field[i].effecter_state);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930294 }
295
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930296 rc = pldm_msgbuf_destroy(buf);
297 if (rc) {
298 return pldm_xlate_errno(rc);
299 }
300
301 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930302}
303
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930304LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930305int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
306 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
307 uint8_t *transfer_op_flag, uint16_t *request_cnt,
308 uint16_t *record_chg_num)
309{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930310 struct pldm_msgbuf _buf;
311 struct pldm_msgbuf *buf = &_buf;
312 int rc;
313
Andrew Jeffery9c766792022-08-10 23:12:49 +0930314 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
315 transfer_op_flag == NULL || request_cnt == NULL ||
316 record_chg_num == NULL) {
317 return PLDM_ERROR_INVALID_DATA;
318 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930319
Andrew Jeffery9c766792022-08-10 23:12:49 +0930320 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
321 return PLDM_ERROR_INVALID_LENGTH;
322 }
323
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930324 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
325 payload_length);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930326 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930327 return pldm_xlate_errno(rc);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930328 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930329
Andrew Jeffery66c77232024-04-24 11:42:02 +0930330 pldm_msgbuf_extract_p(buf, record_hndl);
331 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
332 pldm_msgbuf_extract_p(buf, transfer_op_flag);
333 pldm_msgbuf_extract_p(buf, request_cnt);
334 pldm_msgbuf_extract_p(buf, record_chg_num);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930335
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930336 rc = pldm_msgbuf_destroy(buf);
337 if (rc) {
338 return pldm_xlate_errno(rc);
339 }
340
341 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930342}
343
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930344LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930345int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
346 uint32_t next_record_hndl,
347 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
348 uint16_t resp_cnt, const uint8_t *record_data,
349 uint8_t transfer_crc, struct pldm_msg *msg)
350{
351 if (msg == NULL) {
352 return PLDM_ERROR_INVALID_DATA;
353 }
354
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930355 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930356 header.msg_type = PLDM_RESPONSE;
357 header.instance = instance_id;
358 header.pldm_type = PLDM_PLATFORM;
359 header.command = PLDM_GET_PDR;
360
361 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
362 if (rc != PLDM_SUCCESS) {
363 return rc;
364 }
365
366 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930367 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930368 response->completion_code = completion_code;
369
370 if (response->completion_code == PLDM_SUCCESS) {
371 response->next_record_handle = htole32(next_record_hndl);
372 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930373 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930374 response->transfer_flag = transfer_flag;
375 response->response_count = htole16(resp_cnt);
376 if (record_data != NULL && resp_cnt > 0) {
377 memcpy(response->record_data, record_data, resp_cnt);
378 }
379 if (transfer_flag == PLDM_END) {
380 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930381 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
382 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930383 *dst = transfer_crc;
384 }
385 }
386
387 return PLDM_SUCCESS;
388}
389
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930390LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930391int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930392 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
393 const uint8_t *update_time, const uint8_t *oem_update_time,
394 uint32_t record_count, uint32_t repository_size,
395 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
396 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930397{
398 if (msg == NULL) {
399 return PLDM_ERROR_INVALID_DATA;
400 }
401
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930402 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930403 header.msg_type = PLDM_RESPONSE;
404 header.instance = instance_id;
405 header.pldm_type = PLDM_PLATFORM;
406 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
407
408 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
409 if (rc != PLDM_SUCCESS) {
410 return rc;
411 }
412
413 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930414 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930415 response->completion_code = completion_code;
416
417 if (response->completion_code == PLDM_SUCCESS) {
418 response->repository_state = repository_state;
419 if (update_time != NULL) {
420 memcpy(response->update_time, update_time,
421 PLDM_TIMESTAMP104_SIZE);
422 }
423 if (oem_update_time != NULL) {
424 memcpy(response->oem_update_time, oem_update_time,
425 PLDM_TIMESTAMP104_SIZE);
426 }
427 response->record_count = htole32(record_count);
428 response->repository_size = htole32(repository_size);
429 response->largest_record_size = htole32(largest_record_size);
430 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930431 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930432 }
433
434 return PLDM_SUCCESS;
435}
436
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000437LIBPLDM_ABI_DEPRECATED
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800438int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930439 const struct pldm_msg *msg, size_t payload_length,
440 uint8_t *completion_code, uint8_t *repository_state,
441 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
442 uint32_t *repository_size, uint32_t *largest_record_size,
443 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800444{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930445 struct pldm_msgbuf _buf;
446 struct pldm_msgbuf *buf = &_buf;
447 int rc;
448
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800449 if (msg == NULL || completion_code == NULL ||
450 repository_state == NULL || update_time == NULL ||
451 oem_update_time == NULL || record_count == NULL ||
452 repository_size == NULL || largest_record_size == NULL ||
453 data_transfer_handle_timeout == NULL) {
454 return PLDM_ERROR_INVALID_DATA;
455 }
456
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930457 rc = pldm_msgbuf_init_errno(buf,
458 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
459 msg->payload, payload_length);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930460 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930461 return pldm_xlate_errno(rc);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930462 }
463
Andrew Jeffery66c77232024-04-24 11:42:02 +0930464 pldm_msgbuf_extract_p(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800465 if (PLDM_SUCCESS != *completion_code) {
466 return PLDM_SUCCESS;
467 }
468
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930469 rc = pldm_msgbuf_extract_p(buf, repository_state);
470 if (rc) {
471 return pldm_xlate_errno(rc);
472 }
473
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800474 if (*repository_state > PLDM_FAILED) {
475 return PLDM_ERROR_INVALID_DATA;
476 }
477
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000478 /* NOTE: Memory safety */
479 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
480 PLDM_TIMESTAMP104_SIZE);
481 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930482 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000483 }
484
485 /* NOTE: Memory safety */
486 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
487 oem_update_time, PLDM_TIMESTAMP104_SIZE);
488 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930489 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000490 }
491
Andrew Jeffery66c77232024-04-24 11:42:02 +0930492 pldm_msgbuf_extract_p(buf, record_count);
493 pldm_msgbuf_extract_p(buf, repository_size);
494 pldm_msgbuf_extract_p(buf, largest_record_size);
495 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800496
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930497 rc = pldm_msgbuf_destroy(buf);
498 if (rc) {
499 return pldm_xlate_errno(rc);
500 }
501
502 return PLDM_SUCCESS;
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800503}
504
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000505LIBPLDM_ABI_TESTING
506int decode_get_pdr_repository_info_resp_safe(
507 const struct pldm_msg *msg, size_t payload_length,
508 struct pldm_pdr_repository_info_resp *resp)
509{
510 struct pldm_msgbuf _buf;
511 struct pldm_msgbuf *buf = &_buf;
512 int rc;
513
514 if (msg == NULL || resp == NULL) {
515 return -EINVAL;
516 }
517
518 rc = pldm_msg_has_error(msg, payload_length);
519 if (rc) {
520 resp->completion_code = rc;
521 return 0;
522 }
523
524 rc = pldm_msgbuf_init_errno(buf,
525 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
526 msg->payload, payload_length);
527 if (rc) {
528 return rc;
529 }
530
531 rc = pldm_msgbuf_extract(buf, resp->completion_code);
532 if (rc) {
533 return rc;
534 }
535
536 pldm_msgbuf_extract(buf, resp->repository_state);
537
538 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
539 resp->update_time,
540 sizeof(resp->update_time));
541 if (rc) {
542 return rc;
543 }
544
545 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
546 resp->oem_update_time,
547 sizeof(resp->oem_update_time));
548 if (rc) {
549 return rc;
550 }
551
552 pldm_msgbuf_extract(buf, resp->record_count);
553 pldm_msgbuf_extract(buf, resp->repository_size);
554 pldm_msgbuf_extract(buf, resp->largest_record_size);
555 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
556
557 return pldm_msgbuf_destroy_consumed(buf);
558}
559
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930560LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930561int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
562 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
563 uint16_t request_cnt, uint16_t record_chg_num,
564 struct pldm_msg *msg, size_t payload_length)
565{
566 if (msg == NULL) {
567 return PLDM_ERROR_INVALID_DATA;
568 }
569
570 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
571 return PLDM_ERROR_INVALID_LENGTH;
572 }
573
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930574 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930575 header.msg_type = PLDM_REQUEST;
576 header.instance = instance_id;
577 header.pldm_type = PLDM_PLATFORM;
578 header.command = PLDM_GET_PDR;
579
580 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
581 if (rc != PLDM_SUCCESS) {
582 return rc;
583 }
584
585 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930586 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930587 request->record_handle = htole32(record_hndl);
588 request->data_transfer_handle = htole32(data_transfer_hndl);
589 request->transfer_op_flag = transfer_op_flag;
590 request->request_count = htole16(request_cnt);
591 request->record_change_number = htole16(record_chg_num);
592
593 return PLDM_SUCCESS;
594}
595
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000596LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930597int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
598 uint8_t *completion_code, uint32_t *next_record_hndl,
599 uint32_t *next_data_transfer_hndl,
600 uint8_t *transfer_flag, uint16_t *resp_cnt,
601 uint8_t *record_data, size_t record_data_length,
602 uint8_t *transfer_crc)
603{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930604 struct pldm_msgbuf _buf;
605 struct pldm_msgbuf *buf = &_buf;
606 int rc;
607
Andrew Jeffery9c766792022-08-10 23:12:49 +0930608 if (msg == NULL || completion_code == NULL ||
609 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
610 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
611 return PLDM_ERROR_INVALID_DATA;
612 }
613
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930614 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
615 msg->payload, payload_length);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930616 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930617 return pldm_xlate_errno(rc);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930618 }
619
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930620 rc = pldm_msgbuf_extract_p(buf, completion_code);
621 if (rc) {
622 return pldm_xlate_errno(rc);
623 }
624
Andrew Jeffery9c766792022-08-10 23:12:49 +0930625 if (PLDM_SUCCESS != *completion_code) {
626 return PLDM_SUCCESS;
627 }
628
Andrew Jeffery66c77232024-04-24 11:42:02 +0930629 pldm_msgbuf_extract_p(buf, next_record_hndl);
630 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
631 pldm_msgbuf_extract_p(buf, transfer_flag);
632 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930633 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930634 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930635 }
636
637 if (*resp_cnt > 0 && record_data != NULL) {
638 if (record_data_length < *resp_cnt) {
639 return PLDM_ERROR_INVALID_LENGTH;
640 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000641 /* NOTE: Memory safety */
642 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
643 *resp_cnt);
644 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930645 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000646 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930647 }
648
649 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930650 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930651 }
652
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930653 rc = pldm_msgbuf_destroy(buf);
654 if (rc) {
655 return pldm_xlate_errno(rc);
656 }
657
658 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930659}
660
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000661LIBPLDM_ABI_TESTING
662int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
663 struct pldm_get_pdr_resp *resp, size_t resp_len,
664 uint8_t *transfer_crc)
665{
666 struct pldm_msgbuf _buf;
667 struct pldm_msgbuf *buf = &_buf;
668 int rc;
669
670 if (msg == NULL || resp == NULL || transfer_crc == NULL) {
671 return -EINVAL;
672 }
673
674 rc = pldm_msg_has_error(msg, payload_length);
675 if (rc) {
676 resp->completion_code = rc;
677 return 0;
678 }
679
680 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
681 msg->payload, payload_length);
682 if (rc) {
683 return rc;
684 }
685
686 pldm_msgbuf_extract(buf, resp->completion_code);
687 pldm_msgbuf_extract(buf, resp->next_record_handle);
688 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
689
690 rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
691 if (rc) {
692 return rc;
693 }
694
695 rc = pldm_msgbuf_extract(buf, resp->response_count);
696 if (rc) {
697 return rc;
698 }
699
700 rc = pldm_msgbuf_extract_array(
701 buf, resp->response_count, resp->record_data,
702 resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
703 if (rc) {
704 return rc;
705 }
706
707 if (resp->transfer_flag == PLDM_END) {
708 pldm_msgbuf_extract_p(buf, transfer_crc);
709 }
710
711 return pldm_msgbuf_destroy_consumed(buf);
712}
713
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930714LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930715int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
716 size_t payload_length,
717 uint16_t *effecter_id,
718 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930719 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930720{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930721 struct pldm_msgbuf _buf;
722 struct pldm_msgbuf *buf = &_buf;
723 int rc;
724
Andrew Jeffery9c766792022-08-10 23:12:49 +0930725 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
726 effecter_value == NULL) {
727 return PLDM_ERROR_INVALID_DATA;
728 }
729
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930730 rc = pldm_msgbuf_init_errno(
731 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
732 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930733 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930734 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930735 }
736
Andrew Jeffery66c77232024-04-24 11:42:02 +0930737 pldm_msgbuf_extract_p(buf, effecter_id);
738 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930739 if (rc) {
740 return PLDM_ERROR_INVALID_DATA;
741 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930742
743 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
744 return PLDM_ERROR_INVALID_DATA;
745 }
746
Andrew Jeffery3884c442023-04-12 11:13:24 +0930747 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
748 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930749
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930750 rc = pldm_msgbuf_destroy(buf);
751 if (rc) {
752 return pldm_xlate_errno(rc);
753 }
754
755 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930756}
757
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930758LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930759int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
760 uint8_t completion_code,
761 struct pldm_msg *msg,
762 size_t payload_length)
763{
764 if (msg == NULL) {
765 return PLDM_ERROR_INVALID_DATA;
766 }
767
768 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
769 return PLDM_ERROR_INVALID_LENGTH;
770 }
771
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930772 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930773 header.msg_type = PLDM_RESPONSE;
774 header.instance = instance_id;
775 header.pldm_type = PLDM_PLATFORM;
776 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
777
778 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
779 if (rc != PLDM_SUCCESS) {
780 return rc;
781 }
782
783 msg->payload[0] = completion_code;
784
785 return rc;
786}
787
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930788LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930789int encode_set_numeric_effecter_value_req(uint8_t instance_id,
790 uint16_t effecter_id,
791 uint8_t effecter_data_size,
792 const uint8_t *effecter_value,
793 struct pldm_msg *msg,
794 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930795{
796 if (msg == NULL || effecter_value == NULL) {
797 return PLDM_ERROR_INVALID_DATA;
798 }
799
800 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
801 return PLDM_ERROR_INVALID_DATA;
802 }
803
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930804 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930805 header.msg_type = PLDM_REQUEST;
806 header.instance = instance_id;
807 header.pldm_type = PLDM_PLATFORM;
808 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
809
810 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
811 if (rc != PLDM_SUCCESS) {
812 return rc;
813 }
814
815 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930816 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930817 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
818 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
819 if (payload_length !=
820 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
821 return PLDM_ERROR_INVALID_LENGTH;
822 }
823 request->effecter_value[0] = *effecter_value;
824 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
825 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
826 if (payload_length !=
827 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
828 return PLDM_ERROR_INVALID_LENGTH;
829 }
830
831 uint16_t val = *(uint16_t *)(effecter_value);
832 val = htole16(val);
833 memcpy(request->effecter_value, &val, sizeof(uint16_t));
834
835 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
836 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
837 if (payload_length !=
838 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
839 return PLDM_ERROR_INVALID_LENGTH;
840 }
841
842 uint32_t val = *(uint32_t *)(effecter_value);
843 val = htole32(val);
844 memcpy(request->effecter_value, &val, sizeof(uint32_t));
845 }
846
847 request->effecter_id = htole16(effecter_id);
848 request->effecter_data_size = effecter_data_size;
849
850 return PLDM_SUCCESS;
851}
852
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930853LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930854int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
855 size_t payload_length,
856 uint8_t *completion_code)
857{
858 if (msg == NULL || completion_code == NULL) {
859 return PLDM_ERROR_INVALID_DATA;
860 }
861
862 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
863 return PLDM_ERROR_INVALID_LENGTH;
864 }
865
866 *completion_code = msg->payload[0];
867
868 return PLDM_SUCCESS;
869}
870
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930871LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930872int encode_get_state_sensor_readings_resp(uint8_t instance_id,
873 uint8_t completion_code,
874 uint8_t comp_sensor_count,
875 get_sensor_state_field *field,
876 struct pldm_msg *msg)
877{
878 if (msg == NULL) {
879 return PLDM_ERROR_INVALID_DATA;
880 }
881
882 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
883 return PLDM_ERROR_INVALID_DATA;
884 }
885
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930886 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930887 header.msg_type = PLDM_RESPONSE;
888 header.instance = instance_id;
889 header.pldm_type = PLDM_PLATFORM;
890 header.command = PLDM_GET_STATE_SENSOR_READINGS;
891
892 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
893 if (rc != PLDM_SUCCESS) {
894 return rc;
895 }
896
897 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930898 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930899
900 response->completion_code = completion_code;
901 response->comp_sensor_count = comp_sensor_count;
902 memcpy(response->field, field,
903 (sizeof(get_sensor_state_field) * comp_sensor_count));
904
905 return PLDM_SUCCESS;
906}
907
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930908LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930909int encode_get_state_sensor_readings_req(uint8_t instance_id,
910 uint16_t sensor_id,
911 bitfield8_t sensor_rearm,
912 uint8_t reserved, struct pldm_msg *msg)
913{
914 if (msg == NULL) {
915 return PLDM_ERROR_INVALID_DATA;
916 }
917
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930918 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930919 header.msg_type = PLDM_REQUEST;
920 header.instance = instance_id;
921 header.pldm_type = PLDM_PLATFORM;
922 header.command = PLDM_GET_STATE_SENSOR_READINGS;
923
924 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
925 if (rc != PLDM_SUCCESS) {
926 return rc;
927 }
928
929 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930930 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930931
932 request->sensor_id = htole16(sensor_id);
933 request->reserved = reserved;
934 request->sensor_rearm = sensor_rearm;
935
936 return PLDM_SUCCESS;
937}
938
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930939LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930940int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
941 size_t payload_length,
942 uint8_t *completion_code,
943 uint8_t *comp_sensor_count,
944 get_sensor_state_field *field)
945{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930946 struct pldm_msgbuf _buf;
947 struct pldm_msgbuf *buf = &_buf;
948 uint8_t i;
949 int rc;
950
Andrew Jeffery9c766792022-08-10 23:12:49 +0930951 if (msg == NULL || completion_code == NULL ||
952 comp_sensor_count == NULL || field == NULL) {
953 return PLDM_ERROR_INVALID_DATA;
954 }
955
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930956 rc = pldm_msgbuf_init_errno(
957 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
958 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930959 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930960 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930961 }
962
Andrew Jeffery66c77232024-04-24 11:42:02 +0930963 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930964 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930965 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930966 }
967
Andrew Jeffery9c766792022-08-10 23:12:49 +0930968 if (PLDM_SUCCESS != *completion_code) {
969 return PLDM_SUCCESS;
970 }
971
Andrew Jeffery66c77232024-04-24 11:42:02 +0930972 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930973 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930974 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930975 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930976
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930977 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930978 return PLDM_ERROR_INVALID_DATA;
979 }
980
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930981 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930982 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
983 pldm_msgbuf_extract(buf, field[i].present_state);
984 pldm_msgbuf_extract(buf, field[i].previous_state);
985 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930986 }
987
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930988 rc = pldm_msgbuf_destroy_consumed(buf);
989 if (rc) {
990 return pldm_xlate_errno(rc);
991 }
992
993 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930994}
995
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930996LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930997int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
998 size_t payload_length,
999 uint16_t *sensor_id,
1000 bitfield8_t *sensor_rearm,
1001 uint8_t *reserved)
1002{
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301003 struct pldm_msgbuf _buf;
1004 struct pldm_msgbuf *buf = &_buf;
1005 int rc;
1006
Andrew Jeffery9c766792022-08-10 23:12:49 +09301007 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
1008 return PLDM_ERROR_INVALID_DATA;
1009 }
1010
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301011 rc = pldm_msgbuf_init_errno(buf,
1012 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
1013 msg->payload, payload_length);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301014 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301015 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301016 }
1017
Andrew Jeffery66c77232024-04-24 11:42:02 +09301018 pldm_msgbuf_extract_p(buf, sensor_id);
1019 pldm_msgbuf_extract(buf, sensor_rearm->byte);
1020 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301021
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301022 rc = pldm_msgbuf_destroy(buf);
1023 if (rc) {
1024 return pldm_xlate_errno(rc);
1025 }
1026
1027 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301028}
1029
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301030LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301031int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301032 struct pldm_sensor_event_data *const event_data,
1033 const size_t event_data_size, const uint16_t sensor_id,
1034 const enum sensor_event_class_states sensor_event_class,
1035 const uint8_t sensor_offset, const uint8_t event_state,
1036 const uint8_t previous_event_state,
1037 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301038{
1039 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301040 (sizeof(*event_data) - sizeof(event_data->event_class) +
1041 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301042
1043 if (!event_data) {
1044 return PLDM_SUCCESS;
1045 }
1046
1047 if (event_data_size < *actual_event_data_size) {
1048 *actual_event_data_size = 0;
1049 return PLDM_ERROR_INVALID_LENGTH;
1050 }
1051
1052 event_data->sensor_id = htole16(sensor_id);
1053 event_data->sensor_event_class_type = sensor_event_class;
1054
1055 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301056 (struct pldm_sensor_event_state_sensor_state *)
1057 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301058
1059 state_data->sensor_offset = sensor_offset;
1060 state_data->event_state = event_state;
1061 state_data->previous_event_state = previous_event_state;
1062
1063 return PLDM_SUCCESS;
1064}
1065
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301066LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301067int decode_platform_event_message_req(const struct pldm_msg *msg,
1068 size_t payload_length,
1069 uint8_t *format_version, uint8_t *tid,
1070 uint8_t *event_class,
1071 size_t *event_data_offset)
1072{
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301073 struct pldm_msgbuf _buf;
1074 struct pldm_msgbuf *buf = &_buf;
1075 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301076
1077 if (msg == NULL || format_version == NULL || tid == NULL ||
1078 event_class == NULL || event_data_offset == NULL) {
1079 return PLDM_ERROR_INVALID_DATA;
1080 }
1081
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301082 rc = pldm_msgbuf_init_errno(buf,
1083 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
1084 msg->payload, payload_length);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301085 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301086 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301087 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301088
Andrew Jeffery66c77232024-04-24 11:42:02 +09301089 pldm_msgbuf_extract_p(buf, format_version);
1090 pldm_msgbuf_extract_p(buf, tid);
1091 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301092
1093 rc = pldm_msgbuf_destroy(buf);
1094 if (rc) {
1095 return pldm_xlate_errno(rc);
1096 }
1097
Andrew Jeffery9c766792022-08-10 23:12:49 +09301098 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301099 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301100
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301101 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301102}
1103
Thu Nguyen387b10f2024-09-24 11:33:16 +00001104static int pldm_platform_poll_for_platform_event_message_validate(
1105 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1106{
1107 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1108 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1109 ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1110 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1111 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
Thu Nguyen9e16b182024-10-01 03:12:16 +00001112 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1113 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1114 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
Thu Nguyen387b10f2024-09-24 11:33:16 +00001115 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1116 return -EPROTO;
1117 }
1118
1119 return 0;
1120}
1121
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301122LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001123int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301124 const struct pldm_msg *msg, size_t payload_length,
1125 uint8_t *format_version, uint8_t *transfer_operation_flag,
1126 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001127{
1128 struct pldm_msgbuf _buf;
1129 struct pldm_msgbuf *buf = &_buf;
1130 int rc;
1131
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001132 if (msg == NULL || format_version == NULL ||
1133 transfer_operation_flag == NULL || data_transfer_handle == NULL ||
1134 event_id_to_acknowledge == NULL) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001135 return PLDM_ERROR_INVALID_DATA;
1136 }
1137
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301138 rc = pldm_msgbuf_init_errno(
1139 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
1140 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001141 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301142 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001143 }
1144
Andrew Jeffery66c77232024-04-24 11:42:02 +09301145 pldm_msgbuf_extract_p(buf, format_version);
1146 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001147 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301148 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001149 }
1150 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
1151 return PLDM_ERROR_INVALID_DATA;
1152 }
1153
Andrew Jeffery66c77232024-04-24 11:42:02 +09301154 pldm_msgbuf_extract_p(buf, data_transfer_handle);
1155 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001156 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301157 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001158 }
1159
Thu Nguyen387b10f2024-09-24 11:33:16 +00001160 rc = pldm_platform_poll_for_platform_event_message_validate(
1161 *transfer_operation_flag, *event_id_to_acknowledge);
1162 if (rc < 0) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001163 return PLDM_ERROR_INVALID_DATA;
1164 }
1165
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301166 rc = pldm_msgbuf_destroy(buf);
1167 if (rc) {
1168 return pldm_xlate_errno(rc);
1169 }
1170
1171 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001172}
1173
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301174LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301175int encode_platform_event_message_resp(uint8_t instance_id,
1176 uint8_t completion_code,
1177 uint8_t platform_event_status,
1178 struct pldm_msg *msg)
1179{
1180 if (msg == NULL) {
1181 return PLDM_ERROR_INVALID_DATA;
1182 }
1183
1184 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1185 return PLDM_ERROR_INVALID_DATA;
1186 }
1187
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301188 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301189 header.msg_type = PLDM_RESPONSE;
1190 header.instance = instance_id;
1191 header.pldm_type = PLDM_PLATFORM;
1192 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1193
1194 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1195 if (rc != PLDM_SUCCESS) {
1196 return rc;
1197 }
1198
1199 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301200 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301201 response->completion_code = completion_code;
1202 response->platform_event_status = platform_event_status;
1203
1204 return PLDM_SUCCESS;
1205}
1206
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301207LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001208int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301209 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1210 uint16_t event_id, uint32_t next_data_transfer_handle,
1211 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1212 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1213 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001214{
1215 struct pldm_msgbuf _buf;
1216 struct pldm_msgbuf *buf = &_buf;
1217 int rc;
1218
1219 if (!msg) {
1220 return PLDM_ERROR_INVALID_DATA;
1221 }
1222
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301223 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001224 header.msg_type = PLDM_RESPONSE;
1225 header.instance = instance_id;
1226 header.pldm_type = PLDM_PLATFORM;
1227 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1228
1229 rc = pack_pldm_header(&header, &(msg->hdr));
1230 if (rc != PLDM_SUCCESS) {
1231 return rc;
1232 }
1233
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301234 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301235 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1236 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001237 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301238 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001239 }
1240
1241 pldm_msgbuf_insert(buf, completion_code);
1242 pldm_msgbuf_insert(buf, tid);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301243 rc = pldm_msgbuf_insert(buf, event_id);
1244 if (rc) {
1245 return pldm_xlate_errno(rc);
1246 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001247
1248 if (event_id == 0xffff || event_id == 0x0000) {
1249 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1250 payload_length) {
1251 return PLDM_ERROR_INVALID_LENGTH;
1252 }
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301253
1254 rc = pldm_msgbuf_destroy(buf);
1255 if (rc) {
1256 return pldm_xlate_errno(rc);
1257 }
1258
1259 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001260 }
1261
1262 if ((event_data == NULL) && (event_data_size > 0)) {
1263 return PLDM_ERROR_INVALID_DATA;
1264 }
1265
1266 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1267 pldm_msgbuf_insert(buf, transfer_flag);
1268 pldm_msgbuf_insert(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301269 rc = pldm_msgbuf_insert(buf, event_data_size);
1270 if (rc) {
1271 return pldm_xlate_errno(rc);
1272 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001273
1274 if ((event_data_size > 0) && event_data) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001275 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
1276 event_data_size);
1277 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301278 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001279 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001280 }
1281
1282 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1283 pldm_msgbuf_insert(buf, checksum);
1284 }
1285
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301286 rc = pldm_msgbuf_destroy(buf);
1287 if (rc) {
1288 return pldm_xlate_errno(rc);
1289 }
1290
1291 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001292}
1293
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301294LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301295int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301296 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1297 uint8_t event_class, const uint8_t *event_data,
1298 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301299
1300{
1301 if (format_version != 1) {
1302 return PLDM_ERROR_INVALID_DATA;
1303 }
1304
1305 if (msg == NULL || event_data == NULL) {
1306 return PLDM_ERROR_INVALID_DATA;
1307 }
1308
1309 if (event_data_length == 0) {
1310 return PLDM_ERROR_INVALID_DATA;
1311 }
1312
1313 if (payload_length !=
1314 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1315 return PLDM_ERROR_INVALID_LENGTH;
1316 }
1317
John Chungb43a7782024-09-26 22:04:27 +08001318 if (event_class > PLDM_CPER_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001319 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301320 return PLDM_ERROR_INVALID_DATA;
1321 }
1322
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301323 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301324 header.msg_type = PLDM_REQUEST;
1325 header.instance = instance_id;
1326 header.pldm_type = PLDM_PLATFORM;
1327 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1328
1329 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1330 if (rc != PLDM_SUCCESS) {
1331 return rc;
1332 }
1333
1334 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301335 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301336 request->format_version = format_version;
1337 request->tid = tid;
1338 request->event_class = event_class;
1339 memcpy(request->event_data, event_data, event_data_length);
1340
1341 return PLDM_SUCCESS;
1342}
1343
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301344LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301345int decode_platform_event_message_resp(const struct pldm_msg *msg,
1346 size_t payload_length,
1347 uint8_t *completion_code,
1348 uint8_t *platform_event_status)
1349{
Andrew Jefferye5011772023-04-13 12:06:22 +09301350 struct pldm_msgbuf _buf;
1351 struct pldm_msgbuf *buf = &_buf;
1352 int rc;
1353
Andrew Jeffery9c766792022-08-10 23:12:49 +09301354 if (msg == NULL || completion_code == NULL ||
1355 platform_event_status == NULL) {
1356 return PLDM_ERROR_INVALID_DATA;
1357 }
1358
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301359 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1360 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301361 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301362 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301363 }
1364
Andrew Jeffery66c77232024-04-24 11:42:02 +09301365 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301366 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301367 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301368 }
1369
Andrew Jeffery9c766792022-08-10 23:12:49 +09301370 if (PLDM_SUCCESS != *completion_code) {
1371 return PLDM_SUCCESS;
1372 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301373
Andrew Jeffery66c77232024-04-24 11:42:02 +09301374 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301375 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301376 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301377 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301378
1379 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1380 return PLDM_ERROR_INVALID_DATA;
1381 }
1382
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301383 rc = pldm_msgbuf_destroy(buf);
1384 if (rc) {
1385 return pldm_xlate_errno(rc);
1386 }
1387
1388 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301389}
1390
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301391LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301392int encode_event_message_buffer_size_req(uint8_t instance_id,
1393 uint16_t event_receiver_max_buffer_size,
1394 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001395{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301396 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001397 header.msg_type = PLDM_REQUEST;
1398 header.instance = instance_id;
1399 header.pldm_type = PLDM_PLATFORM;
1400 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1401
1402 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1403 if (rc != PLDM_SUCCESS) {
1404 return rc;
1405 }
1406
1407 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301408 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001409 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301410 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001411
1412 return PLDM_SUCCESS;
1413}
1414
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301415LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001416int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1417 size_t payload_length,
1418 uint8_t *completion_code,
1419 uint16_t *terminus_max_buffer_size)
1420{
Andrew Jeffery11126902023-04-13 12:12:10 +09301421 struct pldm_msgbuf _buf;
1422 struct pldm_msgbuf *buf = &_buf;
1423 int rc;
1424
Dung Caod6ae8982022-11-02 10:00:10 +07001425 if (msg == NULL || completion_code == NULL ||
1426 terminus_max_buffer_size == NULL) {
1427 return PLDM_ERROR_INVALID_DATA;
1428 }
1429
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301430 rc = pldm_msgbuf_init_errno(buf,
1431 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1432 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301433 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301434 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301435 }
1436
Andrew Jeffery66c77232024-04-24 11:42:02 +09301437 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301438 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301439 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301440 }
1441
Dung Caod6ae8982022-11-02 10:00:10 +07001442 if (PLDM_SUCCESS != *completion_code) {
1443 return PLDM_SUCCESS;
1444 }
Dung Caod6ae8982022-11-02 10:00:10 +07001445
Andrew Jeffery66c77232024-04-24 11:42:02 +09301446 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001447
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301448 rc = pldm_msgbuf_destroy_consumed(buf);
1449 if (rc) {
1450 return pldm_xlate_errno(rc);
1451 }
1452
1453 return PLDM_SUCCESS;
Dung Caod6ae8982022-11-02 10:00:10 +07001454}
1455
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301456LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001457int encode_event_message_supported_req(uint8_t instance_id,
1458 uint8_t format_version,
1459 struct pldm_msg *msg)
1460{
1461 if (format_version != 1) {
1462 return PLDM_ERROR_INVALID_DATA;
1463 }
1464
1465 if (msg == NULL) {
1466 return PLDM_ERROR_INVALID_DATA;
1467 }
1468
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301469 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001470 header.msg_type = PLDM_REQUEST;
1471 header.instance = instance_id;
1472 header.pldm_type = PLDM_PLATFORM;
1473 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1474
1475 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1476 if (rc != PLDM_SUCCESS) {
1477 return rc;
1478 }
1479
1480 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301481 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001482 request->format_version = format_version;
1483
1484 return PLDM_SUCCESS;
1485}
1486
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301487LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301488int decode_event_message_supported_resp(const struct pldm_msg *msg,
1489 size_t payload_length,
1490 uint8_t *completion_code,
1491 uint8_t *synchrony_config,
1492 bitfield8_t *synchrony_config_support,
1493 uint8_t *number_event_class_returned,
1494 uint8_t *event_class,
1495 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001496{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301497 struct pldm_msgbuf _buf;
1498 struct pldm_msgbuf *buf = &_buf;
1499 int i;
1500 int rc;
1501
Dung Cao1bf8c872022-11-29 05:32:58 +07001502 if (msg == NULL || completion_code == NULL ||
1503 synchrony_config == NULL || synchrony_config_support == NULL ||
1504 number_event_class_returned == NULL || event_class == NULL) {
1505 return PLDM_ERROR_INVALID_DATA;
1506 }
1507
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301508 rc = pldm_msgbuf_init_errno(buf,
1509 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1510 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301511 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301512 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301513 }
1514
Andrew Jeffery66c77232024-04-24 11:42:02 +09301515 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301516 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301517 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301518 }
1519
Dung Cao1bf8c872022-11-29 05:32:58 +07001520 if (PLDM_SUCCESS != *completion_code) {
1521 return PLDM_SUCCESS;
1522 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301523
Andrew Jeffery66c77232024-04-24 11:42:02 +09301524 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301525 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301526 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001527 }
1528
Dung Cao1bf8c872022-11-29 05:32:58 +07001529 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1530 return PLDM_ERROR_INVALID_DATA;
1531 }
1532
Andrew Jeffery66c77232024-04-24 11:42:02 +09301533 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001534
Andrew Jeffery66c77232024-04-24 11:42:02 +09301535 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301536 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301537 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001538 }
1539
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301540 if (*number_event_class_returned == 0) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301541 rc = pldm_msgbuf_destroy(buf);
1542 if (rc) {
1543 return pldm_xlate_errno(rc);
1544 }
1545
1546 return PLDM_SUCCESS;
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301547 }
1548
1549 if (event_class_count < *number_event_class_returned) {
1550 return PLDM_ERROR_INVALID_LENGTH;
1551 }
1552
1553 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301554 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301555 }
1556
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301557 rc = pldm_msgbuf_destroy_consumed(buf);
1558 if (rc) {
1559 return pldm_xlate_errno(rc);
1560 }
1561
1562 return PLDM_SUCCESS;
Dung Cao1bf8c872022-11-29 05:32:58 +07001563}
1564
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301565LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301566int decode_sensor_event_data(const uint8_t *event_data,
1567 size_t event_data_length, uint16_t *sensor_id,
1568 uint8_t *sensor_event_class_type,
1569 size_t *event_class_data_offset)
1570{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301571 struct pldm_msgbuf _buf;
1572 struct pldm_msgbuf *buf = &_buf;
1573 int rc;
1574
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001575 if (event_data == NULL || sensor_id == NULL ||
1576 sensor_event_class_type == NULL ||
1577 event_class_data_offset == NULL) {
1578 return PLDM_ERROR_INVALID_DATA;
1579 }
1580
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301581 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1582 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301583 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301584 return pldm_xlate_errno(rc);
1585 }
1586
1587 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1588 return PLDM_ERROR_INVALID_LENGTH;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301589 }
1590
1591 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301592 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301593
Andrew Jeffery66c77232024-04-24 11:42:02 +09301594 pldm_msgbuf_extract_p(buf, sensor_id);
1595 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301596 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301597 return pldm_xlate_errno(rc);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301598 }
1599
1600 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301601 if (event_class_data_length !=
1602 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1603 return PLDM_ERROR_INVALID_LENGTH;
1604 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301605 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301606 if (event_class_data_length !=
1607 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1608 return PLDM_ERROR_INVALID_LENGTH;
1609 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301610 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301611 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301612 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301613 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301614 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301615 return PLDM_ERROR_INVALID_LENGTH;
1616 }
1617 } else {
1618 return PLDM_ERROR_INVALID_DATA;
1619 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301620
Andrew Jeffery9c766792022-08-10 23:12:49 +09301621 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301622 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301623
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301624 rc = pldm_msgbuf_destroy(buf);
1625 if (rc) {
1626 return pldm_xlate_errno(rc);
1627 }
1628
1629 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301630}
1631
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301632LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301633int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1634 uint8_t *present_op_state, uint8_t *previous_op_state)
1635{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301636 struct pldm_msgbuf _buf;
1637 struct pldm_msgbuf *buf = &_buf;
1638 int rc;
1639
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001640 if (sensor_data == NULL || present_op_state == NULL ||
1641 previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301642 return PLDM_ERROR_INVALID_DATA;
1643 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301644
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301645 rc = pldm_msgbuf_init_errno(
1646 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1647 sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301648 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301649 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301650 }
1651
Andrew Jeffery66c77232024-04-24 11:42:02 +09301652 pldm_msgbuf_extract_p(buf, present_op_state);
1653 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301654
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301655 rc = pldm_msgbuf_destroy_consumed(buf);
1656 if (rc) {
1657 return pldm_xlate_errno(rc);
1658 }
1659
1660 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301661}
1662
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301663LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301664int decode_state_sensor_data(const uint8_t *sensor_data,
1665 size_t sensor_data_length, uint8_t *sensor_offset,
1666 uint8_t *event_state,
1667 uint8_t *previous_event_state)
1668{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301669 struct pldm_msgbuf _buf;
1670 struct pldm_msgbuf *buf = &_buf;
1671 int rc;
1672
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001673 if (sensor_data == NULL || sensor_offset == NULL ||
1674 event_state == NULL || previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301675 return PLDM_ERROR_INVALID_DATA;
1676 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301677
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301678 rc = pldm_msgbuf_init_errno(
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301679 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1680 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301681 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301682 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301683 }
1684
Andrew Jeffery66c77232024-04-24 11:42:02 +09301685 pldm_msgbuf_extract_p(buf, sensor_offset);
1686 pldm_msgbuf_extract_p(buf, event_state);
1687 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301688
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301689 rc = pldm_msgbuf_destroy_consumed(buf);
1690 if (rc) {
1691 return pldm_xlate_errno(rc);
1692 }
1693
1694 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301695}
1696
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301697LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301698int decode_numeric_sensor_data(const uint8_t *sensor_data,
1699 size_t sensor_data_length, uint8_t *event_state,
1700 uint8_t *previous_event_state,
1701 uint8_t *sensor_data_size,
1702 uint32_t *present_reading)
1703{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301704 struct pldm_msgbuf _buf;
1705 struct pldm_msgbuf *buf = &_buf;
1706 int rc;
1707
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001708 if (sensor_data == NULL || sensor_data_size == NULL ||
1709 event_state == NULL || previous_event_state == NULL ||
1710 present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301711 return PLDM_ERROR_INVALID_DATA;
1712 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301713
1714 if (sensor_data_length >
1715 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301716 return PLDM_ERROR_INVALID_LENGTH;
1717 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301718
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301719 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301720 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1721 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301722 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301723 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301724 }
1725
Andrew Jeffery66c77232024-04-24 11:42:02 +09301726 pldm_msgbuf_extract_p(buf, event_state);
1727 pldm_msgbuf_extract_p(buf, previous_event_state);
1728 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301729 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301730 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301731 }
1732
1733 /*
1734 * The implementation below is bonkers, but it's because the function
1735 * prototype is bonkers. The `present_reading` argument should have been
1736 * a tagged union.
1737 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301738 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301739 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1740 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301741 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301742 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301743 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301744 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301745 }
1746 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1747 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301748 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301749 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301750 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301751 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301752 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301753 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301754 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301755 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301756 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301757 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301758 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301759 }
1760 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301761 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301762 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301763 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301764 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301765 break;
1766 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301767 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1768 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301769 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301770 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301771 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301772 break;
1773 }
1774 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1775 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301776 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301777 *present_reading = (uint32_t)val;
1778 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301779 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301780 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301781 default:
1782 return PLDM_ERROR_INVALID_DATA;
1783 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301784
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301785 rc = pldm_msgbuf_destroy_consumed(buf);
1786 if (rc) {
1787 return pldm_xlate_errno(rc);
1788 }
1789
1790 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301791}
1792
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301793LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301794int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301795 const void *pdr_data, size_t pdr_data_length,
1796 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301797{
1798 struct pldm_msgbuf _buf;
1799 struct pldm_msgbuf *buf = &_buf;
1800 int rc;
1801
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301802 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1803 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301804 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301805 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301806 }
1807
1808 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1809 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301810 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301811 }
1812
1813 rc = pldm_platform_pdr_hdr_validate(
Thu Nguyen51230a02023-11-10 16:22:25 +07001814 &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301815 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301816 if (rc) {
1817 return rc;
1818 }
1819
Andrew Jeffery66c77232024-04-24 11:42:02 +09301820 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1821 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1822 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1823 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1824 pldm_msgbuf_extract(buf, pdr_value->container_id);
1825 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1826 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1827 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1828 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1829 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1830 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1831 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1832 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1833 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1834 pldm_msgbuf_extract(buf, pdr_value->rel);
1835 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1836 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301837
Andrew Jeffery66c77232024-04-24 11:42:02 +09301838 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301839 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301840 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301841 }
1842 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1843 return PLDM_ERROR_INVALID_DATA;
1844 }
1845
Andrew Jeffery66c77232024-04-24 11:42:02 +09301846 pldm_msgbuf_extract(buf, pdr_value->resolution);
1847 pldm_msgbuf_extract(buf, pdr_value->offset);
1848 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1849 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1850 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301851 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1852 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301853 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301854 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301855 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1856 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1857 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301858 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1859 &pdr_value->max_readable);
1860 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1861 &pdr_value->min_readable);
1862
Andrew Jeffery66c77232024-04-24 11:42:02 +09301863 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301864 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301865 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301866 }
1867 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1868 return PLDM_ERROR_INVALID_DATA;
1869 }
1870
Andrew Jeffery66c77232024-04-24 11:42:02 +09301871 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301872 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301873 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301874 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301875 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301876 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301877 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301878 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301879 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301880 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301881 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301882 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301883 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301884 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301885 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301886 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301887 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301888 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301889 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301890
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301891 rc = pldm_msgbuf_destroy(buf);
1892 if (rc) {
1893 return pldm_xlate_errno(rc);
1894 }
1895
1896 return PLDM_SUCCESS;
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301897}
1898
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301899LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301900int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1901 uint16_t effecter_id,
1902 struct pldm_msg *msg)
1903{
1904 if (msg == NULL) {
1905 return PLDM_ERROR_INVALID_DATA;
1906 }
1907
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301908 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301909 header.msg_type = PLDM_REQUEST;
1910 header.instance = instance_id;
1911 header.pldm_type = PLDM_PLATFORM;
1912 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1913
1914 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1915 if (rc != PLDM_SUCCESS) {
1916 return rc;
1917 }
1918
1919 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301920 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301921 request->effecter_id = htole16(effecter_id);
1922
1923 return PLDM_SUCCESS;
1924}
1925
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301926LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301927int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301928 uint8_t instance_id, uint8_t completion_code,
1929 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1930 const uint8_t *pending_value, const uint8_t *present_value,
1931 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301932{
1933 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1934 return PLDM_ERROR_INVALID_DATA;
1935 }
1936
1937 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1938 return PLDM_ERROR_INVALID_DATA;
1939 }
1940
1941 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1942 return PLDM_ERROR_INVALID_DATA;
1943 }
1944
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301945 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301946 header.msg_type = PLDM_RESPONSE;
1947 header.instance = instance_id;
1948 header.pldm_type = PLDM_PLATFORM;
1949 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1950
1951 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1952 if (rc != PLDM_SUCCESS) {
1953 return rc;
1954 }
1955
1956 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301957 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301958
1959 response->completion_code = completion_code;
1960 response->effecter_data_size = effecter_data_size;
1961 response->effecter_oper_state = effecter_oper_state;
1962
1963 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1964 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1965 if (payload_length !=
1966 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1967 return PLDM_ERROR_INVALID_LENGTH;
1968 }
1969 response->pending_and_present_values[0] = *pending_value;
1970 response->pending_and_present_values[1] = *present_value;
1971
1972 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1973 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1974 if (payload_length !=
1975 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1976 return PLDM_ERROR_INVALID_LENGTH;
1977 }
1978 uint16_t val_pending = *(uint16_t *)pending_value;
1979 val_pending = htole16(val_pending);
1980 memcpy(response->pending_and_present_values, &val_pending,
1981 sizeof(uint16_t));
1982 uint16_t val_present = *(uint16_t *)present_value;
1983 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301984 memcpy((response->pending_and_present_values +
1985 sizeof(uint16_t)),
1986 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301987
1988 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1989 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1990 if (payload_length !=
1991 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1992 return PLDM_ERROR_INVALID_LENGTH;
1993 }
1994 uint32_t val_pending = *(uint32_t *)pending_value;
1995 val_pending = htole32(val_pending);
1996 memcpy(response->pending_and_present_values, &val_pending,
1997 sizeof(uint32_t));
1998 uint32_t val_present = *(uint32_t *)present_value;
1999 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302000 memcpy((response->pending_and_present_values +
2001 sizeof(uint32_t)),
2002 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302003 }
2004 return PLDM_SUCCESS;
2005}
2006
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302007LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302008int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
2009 size_t payload_length,
2010 uint16_t *effecter_id)
2011{
Andrew Jefferydd265822023-04-13 22:42:44 +09302012 struct pldm_msgbuf _buf;
2013 struct pldm_msgbuf *buf = &_buf;
2014 int rc;
2015
Andrew Jeffery9c766792022-08-10 23:12:49 +09302016 if (msg == NULL || effecter_id == NULL) {
2017 return PLDM_ERROR_INVALID_DATA;
2018 }
2019
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302020 rc = pldm_msgbuf_init_errno(buf,
2021 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2022 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09302023 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302024 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302025 }
2026
Andrew Jeffery66c77232024-04-24 11:42:02 +09302027 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302028
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302029 rc = pldm_msgbuf_destroy_consumed(buf);
2030 if (rc) {
2031 return pldm_xlate_errno(rc);
2032 }
2033
2034 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302035}
2036
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302037LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302038int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2039 size_t payload_length,
2040 uint8_t *completion_code,
2041 uint8_t *effecter_data_size,
2042 uint8_t *effecter_oper_state,
2043 uint8_t *pending_value,
2044 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302045{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302046 struct pldm_msgbuf _buf;
2047 struct pldm_msgbuf *buf = &_buf;
2048 int rc;
2049
Andrew Jeffery9c766792022-08-10 23:12:49 +09302050 if (msg == NULL || effecter_data_size == NULL ||
2051 effecter_oper_state == NULL || pending_value == NULL ||
2052 present_value == NULL) {
2053 return PLDM_ERROR_INVALID_DATA;
2054 }
2055
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302056 rc = pldm_msgbuf_init_errno(
2057 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2058 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302059 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302060 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302061 }
2062
Andrew Jeffery66c77232024-04-24 11:42:02 +09302063 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302064 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302065 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302066 }
2067
Andrew Jeffery9c766792022-08-10 23:12:49 +09302068 if (PLDM_SUCCESS != *completion_code) {
2069 return PLDM_SUCCESS;
2070 }
2071
Andrew Jeffery66c77232024-04-24 11:42:02 +09302072 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302073 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302074 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302075 }
2076
Andrew Jeffery9c766792022-08-10 23:12:49 +09302077 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2078 return PLDM_ERROR_INVALID_DATA;
2079 }
2080
Andrew Jeffery66c77232024-04-24 11:42:02 +09302081 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302082 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302083 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302084 }
2085
Andrew Jeffery9c766792022-08-10 23:12:49 +09302086 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
2087 return PLDM_ERROR_INVALID_DATA;
2088 }
2089
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302090 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2091 pending_value);
2092 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2093 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302094
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302095 rc = pldm_msgbuf_destroy_consumed(buf);
2096 if (rc) {
2097 return pldm_xlate_errno(rc);
2098 }
2099
2100 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302101}
2102
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302103LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302104int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302105 uint8_t event_data_format, uint8_t number_of_change_records,
2106 const uint8_t *event_data_operations,
2107 const uint8_t *numbers_of_change_entries,
2108 const uint32_t *const *change_entries,
2109 struct pldm_pdr_repository_chg_event_data *event_data,
2110 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302111{
2112 if (event_data_operations == NULL ||
2113 numbers_of_change_entries == NULL || change_entries == NULL) {
2114 return PLDM_ERROR_INVALID_DATA;
2115 }
2116
2117 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302118 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302119
2120 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302121 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302122 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302123 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302124
2125 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302126 expected_size += sizeof(*change_entries[0]) *
2127 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302128 }
2129
2130 *actual_change_records_size = expected_size;
2131
2132 if (event_data == NULL) {
2133 return PLDM_SUCCESS;
2134 }
2135
2136 if (max_change_records_size < expected_size) {
2137 return PLDM_ERROR_INVALID_LENGTH;
2138 }
2139
2140 event_data->event_data_format = event_data_format;
2141 event_data->number_of_change_records = number_of_change_records;
2142
2143 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302144 (struct pldm_pdr_repository_change_record_data *)
2145 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302146
2147 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2148 record_data->event_data_operation = event_data_operations[i];
2149 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302150 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302151
2152 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2153 ++j) {
2154 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302155 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302156 }
2157
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302158 record_data =
2159 (struct pldm_pdr_repository_change_record_data
2160 *)(record_data->change_entry +
2161 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302162 }
2163
2164 return PLDM_SUCCESS;
2165}
2166
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302167LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302168int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2169 size_t event_data_size,
2170 uint8_t *event_data_format,
2171 uint8_t *number_of_change_records,
2172 size_t *change_record_data_offset)
2173{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302174 struct pldm_msgbuf _buf;
2175 struct pldm_msgbuf *buf = &_buf;
2176 int rc;
2177
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002178 if (event_data == NULL || event_data_format == NULL ||
2179 number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302180 change_record_data_offset == NULL) {
2181 return PLDM_ERROR_INVALID_DATA;
2182 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302183
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302184 rc = pldm_msgbuf_init_errno(buf,
2185 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2186 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302187 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302188 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302189 }
2190
Andrew Jeffery66c77232024-04-24 11:42:02 +09302191 pldm_msgbuf_extract_p(buf, event_data_format);
2192 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302193
Andrew Jeffery9c766792022-08-10 23:12:49 +09302194 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302195 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302196
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302197 rc = pldm_msgbuf_destroy(buf);
2198 if (rc) {
2199 return pldm_xlate_errno(rc);
2200 }
2201
2202 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302203}
2204
Thu Nguyenf874b382024-07-24 11:22:34 +00002205LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00002206int decode_pldm_message_poll_event_data(
2207 const void *event_data, size_t event_data_length,
2208 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07002209{
2210 struct pldm_msgbuf _buf;
2211 struct pldm_msgbuf *buf = &_buf;
2212 int rc;
2213
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002214 if (!event_data || !poll_event) {
Thu Nguyen7739d122024-07-26 11:36:39 +00002215 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07002216 }
2217
Thu Nguyen7739d122024-07-26 11:36:39 +00002218 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2219 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002220 if (rc) {
2221 return rc;
2222 }
2223
Thu Nguyen7739d122024-07-26 11:36:39 +00002224 pldm_msgbuf_extract(buf, poll_event->format_version);
2225 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07002226 if (rc) {
2227 return rc;
2228 }
2229
Thu Nguyen7739d122024-07-26 11:36:39 +00002230 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2231 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002232 }
2233
Thu Nguyen7739d122024-07-26 11:36:39 +00002234 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002235
2236 return pldm_msgbuf_destroy_consumed(buf);
2237}
2238
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302239LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00002240int encode_pldm_message_poll_event_data(
2241 const struct pldm_message_poll_event *poll_event, void *event_data,
2242 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07002243{
2244 struct pldm_msgbuf _buf;
2245 struct pldm_msgbuf *buf = &_buf;
2246 int rc;
2247
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002248 if (poll_event == NULL || event_data == NULL) {
2249 return -EINVAL;
2250 }
2251
Thu Nguyen7739d122024-07-26 11:36:39 +00002252 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2253 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002254 }
2255
Thu Nguyen7739d122024-07-26 11:36:39 +00002256 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2257 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002258 if (rc) {
2259 return rc;
2260 }
Thu Nguyen7739d122024-07-26 11:36:39 +00002261 pldm_msgbuf_insert(buf, poll_event->format_version);
2262 pldm_msgbuf_insert(buf, poll_event->event_id);
2263 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002264
Thu Nguyen7739d122024-07-26 11:36:39 +00002265 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002266}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302267
2268LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302269int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302270 const uint8_t *change_record_data, size_t change_record_data_size,
2271 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
2272 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302273{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302274 struct pldm_msgbuf _buf;
2275 struct pldm_msgbuf *buf = &_buf;
2276 int rc;
2277
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002278 if (change_record_data == NULL || event_data_operation == NULL ||
2279 number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302280 change_entry_data_offset == NULL) {
2281 return PLDM_ERROR_INVALID_DATA;
2282 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302283
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302284 rc = pldm_msgbuf_init_errno(
2285 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2286 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302287 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302288 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302289 }
2290
Andrew Jeffery66c77232024-04-24 11:42:02 +09302291 pldm_msgbuf_extract_p(buf, event_data_operation);
2292 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302293
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302294 *change_entry_data_offset = sizeof(*event_data_operation) +
2295 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302296
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302297 rc = pldm_msgbuf_destroy(buf);
2298 if (rc) {
2299 return pldm_xlate_errno(rc);
2300 }
2301
2302 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302303}
2304
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302305LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302306int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2307 uint8_t rearm_event_state,
2308 struct pldm_msg *msg)
2309{
2310 if (msg == NULL) {
2311 return PLDM_ERROR_INVALID_DATA;
2312 }
2313
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302314 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302315 header.msg_type = PLDM_REQUEST;
2316 header.instance = instance_id;
2317 header.pldm_type = PLDM_PLATFORM;
2318 header.command = PLDM_GET_SENSOR_READING;
2319
2320 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2321 if (rc != PLDM_SUCCESS) {
2322 return rc;
2323 }
2324
2325 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302326 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302327
2328 request->sensor_id = htole16(sensor_id);
2329 request->rearm_event_state = rearm_event_state;
2330
2331 return PLDM_SUCCESS;
2332}
2333
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302334LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302335int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302336 const struct pldm_msg *msg, size_t payload_length,
2337 uint8_t *completion_code, uint8_t *sensor_data_size,
2338 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2339 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2340 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302341{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302342 struct pldm_msgbuf _buf;
2343 struct pldm_msgbuf *buf = &_buf;
2344 int rc;
2345
Andrew Jeffery9c766792022-08-10 23:12:49 +09302346 if (msg == NULL || completion_code == NULL ||
2347 sensor_data_size == NULL || sensor_operational_state == NULL ||
2348 sensor_event_message_enable == NULL || present_state == NULL ||
2349 previous_state == NULL || event_state == NULL ||
2350 present_reading == NULL) {
2351 return PLDM_ERROR_INVALID_DATA;
2352 }
2353
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302354 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2355 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302356 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302357 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302358 }
2359
Andrew Jeffery66c77232024-04-24 11:42:02 +09302360 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302361 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302362 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302363 }
2364
Andrew Jeffery9c766792022-08-10 23:12:49 +09302365 if (PLDM_SUCCESS != *completion_code) {
2366 return PLDM_SUCCESS;
2367 }
2368
Andrew Jeffery66c77232024-04-24 11:42:02 +09302369 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302370 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302371 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302372 }
2373
Andrew Jeffery840b1402023-04-13 23:54:44 +09302374 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302375 return PLDM_ERROR_INVALID_DATA;
2376 }
2377
Andrew Jeffery66c77232024-04-24 11:42:02 +09302378 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2379 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2380 pldm_msgbuf_extract_p(buf, present_state);
2381 pldm_msgbuf_extract_p(buf, previous_state);
2382 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302383
Andrew Jeffery840b1402023-04-13 23:54:44 +09302384 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2385 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302386
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302387 rc = pldm_msgbuf_destroy_consumed(buf);
2388 if (rc) {
2389 return pldm_xlate_errno(rc);
2390 }
2391
2392 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302393}
2394
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302395LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302396int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2397 uint8_t sensor_data_size,
2398 uint8_t sensor_operational_state,
2399 uint8_t sensor_event_message_enable,
2400 uint8_t present_state,
2401 uint8_t previous_state, uint8_t event_state,
2402 const uint8_t *present_reading,
2403 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302404{
2405 if (msg == NULL || present_reading == NULL) {
2406 return PLDM_ERROR_INVALID_DATA;
2407 }
2408
2409 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2410 return PLDM_ERROR_INVALID_DATA;
2411 }
2412
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302413 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302414 header.msg_type = PLDM_RESPONSE;
2415 header.instance = instance_id;
2416 header.pldm_type = PLDM_PLATFORM;
2417 header.command = PLDM_GET_SENSOR_READING;
2418
2419 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2420 if (rc != PLDM_SUCCESS) {
2421 return rc;
2422 }
2423
2424 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302425 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302426
2427 response->completion_code = completion_code;
2428 response->sensor_data_size = sensor_data_size;
2429 response->sensor_operational_state = sensor_operational_state;
2430 response->sensor_event_message_enable = sensor_event_message_enable;
2431 response->present_state = present_state;
2432 response->previous_state = previous_state;
2433 response->event_state = event_state;
2434
2435 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2436 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2437 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2438 return PLDM_ERROR_INVALID_LENGTH;
2439 }
2440 response->present_reading[0] = *present_reading;
2441
2442 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2443 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2444 if (payload_length !=
2445 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2446 return PLDM_ERROR_INVALID_LENGTH;
2447 }
2448 uint16_t val = *(uint16_t *)present_reading;
2449 val = htole16(val);
2450 memcpy(response->present_reading, &val, 2);
2451
2452 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2453 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2454 if (payload_length !=
2455 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2456 return PLDM_ERROR_INVALID_LENGTH;
2457 }
2458 uint32_t val = *(uint32_t *)present_reading;
2459 val = htole32(val);
2460 memcpy(response->present_reading, &val, 4);
2461 }
2462
2463 return PLDM_SUCCESS;
2464}
2465
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302466LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302467int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2468 size_t payload_length, uint16_t *sensor_id,
2469 uint8_t *rearm_event_state)
2470{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302471 struct pldm_msgbuf _buf;
2472 struct pldm_msgbuf *buf = &_buf;
2473 int rc;
2474
Andrew Jeffery9c766792022-08-10 23:12:49 +09302475 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2476 return PLDM_ERROR_INVALID_DATA;
2477 }
2478
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302479 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2480 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302481 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302482 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302483 }
2484
Andrew Jeffery66c77232024-04-24 11:42:02 +09302485 pldm_msgbuf_extract_p(buf, sensor_id);
2486 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302487
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302488 rc = pldm_msgbuf_destroy(buf);
2489 if (rc) {
2490 return pldm_xlate_errno(rc);
2491 }
2492
2493 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302494}
2495
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302496LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302497int encode_set_event_receiver_req(uint8_t instance_id,
2498 uint8_t event_message_global_enable,
2499 uint8_t transport_protocol_type,
2500 uint8_t event_receiver_address_info,
2501 uint16_t heartbeat_timer,
2502 struct pldm_msg *msg)
2503{
2504 if (msg == NULL) {
2505 return PLDM_ERROR_INVALID_DATA;
2506 }
2507
2508 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2509 return PLDM_ERROR_INVALID_DATA;
2510 }
2511
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302512 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302513 header.msg_type = PLDM_REQUEST;
2514 header.instance = instance_id;
2515 header.pldm_type = PLDM_PLATFORM;
2516 header.command = PLDM_SET_EVENT_RECEIVER;
2517
2518 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2519 if (rc != PLDM_SUCCESS) {
2520 return rc;
2521 }
2522
2523 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302524 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302525 request->event_message_global_enable = event_message_global_enable;
2526
2527 request->transport_protocol_type = transport_protocol_type;
2528 request->event_receiver_address_info = event_receiver_address_info;
2529
2530 if (event_message_global_enable ==
2531 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2532 if (heartbeat_timer == 0) {
2533 return PLDM_ERROR_INVALID_DATA;
2534 }
2535 request->heartbeat_timer = htole16(heartbeat_timer);
2536 }
2537
2538 return PLDM_SUCCESS;
2539}
2540
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302541LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302542int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2543 size_t payload_length,
2544 uint8_t *completion_code)
2545{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302546 struct pldm_msgbuf _buf;
2547 struct pldm_msgbuf *buf = &_buf;
2548 int rc;
2549
Andrew Jeffery9c766792022-08-10 23:12:49 +09302550 if (msg == NULL || completion_code == NULL) {
2551 return PLDM_ERROR_INVALID_DATA;
2552 }
2553
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302554 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2555 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302556 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302557 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302558 }
2559
Andrew Jeffery66c77232024-04-24 11:42:02 +09302560 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302561
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302562 rc = pldm_msgbuf_destroy(buf);
2563 if (rc) {
2564 return pldm_xlate_errno(rc);
2565 }
2566
2567 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302568}
2569
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302570LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302571int decode_set_event_receiver_req(const struct pldm_msg *msg,
2572 size_t payload_length,
2573 uint8_t *event_message_global_enable,
2574 uint8_t *transport_protocol_type,
2575 uint8_t *event_receiver_address_info,
2576 uint16_t *heartbeat_timer)
2577
2578{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302579 struct pldm_msgbuf _buf;
2580 struct pldm_msgbuf *buf = &_buf;
2581 int rc;
2582
Andrew Jeffery9c766792022-08-10 23:12:49 +09302583 if (msg == NULL || event_message_global_enable == NULL ||
2584 transport_protocol_type == NULL ||
2585 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2586 return PLDM_ERROR_INVALID_DATA;
2587 }
2588
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302589 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2590 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302591 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302592 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302593 }
2594
Andrew Jeffery66c77232024-04-24 11:42:02 +09302595 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2596 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2597 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
Andrew Jeffery2332e052024-10-08 13:52:34 +10302598 pldm_msgbuf_extract_p(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302599
Andrew Jeffery9667f582023-04-14 00:39:21 +09302600 rc = pldm_msgbuf_destroy(buf);
2601 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302602 return pldm_xlate_errno(rc);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302603 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302604
Andrew Jeffery9c766792022-08-10 23:12:49 +09302605 if ((*event_message_global_enable ==
2606 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2607 (*heartbeat_timer == 0)) {
2608 return PLDM_ERROR_INVALID_DATA;
2609 }
2610
Andrew Jeffery9c766792022-08-10 23:12:49 +09302611 return PLDM_SUCCESS;
2612}
2613
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302614LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302615int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2616 struct pldm_msg *msg)
2617
2618{
2619 if (msg == NULL) {
2620 return PLDM_ERROR_INVALID_DATA;
2621 }
2622
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302623 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302624 header.instance = instance_id;
2625 header.msg_type = PLDM_RESPONSE;
2626 header.pldm_type = PLDM_PLATFORM;
2627 header.command = PLDM_SET_EVENT_RECEIVER;
2628
2629 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2630 if (rc != PLDM_SUCCESS) {
2631 return rc;
2632 }
2633
2634 msg->payload[0] = completion_code;
2635
2636 return PLDM_SUCCESS;
2637}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002638
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302639LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002640int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2641 uint8_t format_version,
2642 uint8_t transfer_operation_flag,
2643 uint32_t data_transfer_handle,
2644 uint16_t event_id_to_acknowledge,
2645 struct pldm_msg *msg,
2646 size_t payload_length)
2647{
2648 struct pldm_msgbuf _buf;
2649 struct pldm_msgbuf *buf = &_buf;
2650 int rc;
2651
2652 if (msg == NULL) {
2653 return PLDM_ERROR_INVALID_DATA;
2654 }
2655
Thu Nguyen387b10f2024-09-24 11:33:16 +00002656 rc = pldm_platform_poll_for_platform_event_message_validate(
2657 transfer_operation_flag, event_id_to_acknowledge);
2658 if (rc < 0) {
2659 return PLDM_ERROR_INVALID_DATA;
2660 }
2661
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302662 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002663 header.msg_type = PLDM_REQUEST;
2664 header.instance = instance_id;
2665 header.pldm_type = PLDM_PLATFORM;
2666 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2667
2668 rc = pack_pldm_header(&header, &(msg->hdr));
2669 if (rc != PLDM_SUCCESS) {
2670 return rc;
2671 }
2672
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302673 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302674 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2675 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002676 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302677 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002678 }
2679
2680 pldm_msgbuf_insert(buf, format_version);
2681 pldm_msgbuf_insert(buf, transfer_operation_flag);
2682 pldm_msgbuf_insert(buf, data_transfer_handle);
2683 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2684
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302685 rc = pldm_msgbuf_destroy(buf);
2686 if (rc) {
2687 return pldm_xlate_errno(rc);
2688 }
2689
2690 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002691}
2692
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302693LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002694int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302695 const struct pldm_msg *msg, size_t payload_length,
2696 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2697 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2698 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2699 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002700{
2701 struct pldm_msgbuf _buf;
2702 struct pldm_msgbuf *buf = &_buf;
2703 int rc;
2704
2705 if (msg == NULL || completion_code == NULL || tid == NULL ||
2706 event_id == NULL || next_data_transfer_handle == NULL ||
2707 transfer_flag == NULL || event_class == NULL ||
2708 event_data_size == NULL || event_data == NULL ||
2709 event_data_integrity_checksum == NULL) {
2710 return PLDM_ERROR_INVALID_DATA;
2711 }
2712
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302713 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302714 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2715 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002716 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302717 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002718 }
2719
Andrew Jeffery66c77232024-04-24 11:42:02 +09302720 rc = pldm_msgbuf_extract_p(buf, completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002721 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302722 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002723 }
2724 if (PLDM_SUCCESS != *completion_code) {
2725 return *completion_code;
2726 }
2727
Andrew Jeffery66c77232024-04-24 11:42:02 +09302728 pldm_msgbuf_extract_p(buf, tid);
2729 rc = pldm_msgbuf_extract_p(buf, event_id);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002730 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302731 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002732 }
2733 if ((*event_id == 0) || (*event_id == 0xffff)) {
2734 return PLDM_SUCCESS;
2735 }
2736
Andrew Jeffery66c77232024-04-24 11:42:02 +09302737 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2738 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002739 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302740 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002741 }
2742
Andrew Jeffery66c77232024-04-24 11:42:02 +09302743 pldm_msgbuf_extract_p(buf, event_class);
2744 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002745 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302746 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002747 }
2748 if (*event_data_size > payload_length) {
2749 return PLDM_ERROR_INVALID_DATA;
2750 }
2751
2752 if (*event_data_size > 0) {
2753 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2754 }
2755
2756 if (*transfer_flag == PLDM_END ||
2757 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302758 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002759 }
2760
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302761 rc = pldm_msgbuf_destroy_consumed(buf);
2762 if (rc) {
2763 return pldm_xlate_errno(rc);
2764 }
2765
2766 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002767}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002768
2769LIBPLDM_ABI_TESTING
2770int decode_numeric_effecter_pdr_data(
2771 const void *pdr_data, size_t pdr_data_length,
2772 struct pldm_numeric_effecter_value_pdr *pdr_value)
2773{
2774 struct pldm_msgbuf _buf;
2775 struct pldm_msgbuf *buf = &_buf;
2776 struct pldm_value_pdr_hdr hdr;
2777 int rc;
2778
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002779 if (!pdr_data || !pdr_value) {
2780 return PLDM_ERROR_INVALID_DATA;
2781 }
2782
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302783 rc = pldm_msgbuf_init_errno(buf,
2784 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2785 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002786 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302787 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002788 }
2789
2790 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &hdr);
2791 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302792 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002793 }
2794
2795 rc = pldm_platform_pdr_hdr_validate(
2796 &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2797 pdr_data_length);
2798 if (rc) {
2799 return rc;
2800 }
2801
2802 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2803
2804 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2805 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2806 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2807 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2808 pldm_msgbuf_extract(buf, pdr_value->container_id);
2809 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2810 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2811 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2812 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2813 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2814 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2815 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2816 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2817 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2818 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2819 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2820 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2821
2822 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2823 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302824 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002825 }
2826 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2827 return PLDM_ERROR_INVALID_DATA;
2828 }
2829
2830 pldm_msgbuf_extract(buf, pdr_value->resolution);
2831 pldm_msgbuf_extract(buf, pdr_value->offset);
2832 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2833 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2834 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2835 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2836 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2837 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2838 pdr_value->max_settable);
2839 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2840 pdr_value->min_settable);
2841
2842 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2843 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302844 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002845 }
2846 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2847 return PLDM_ERROR_INVALID_DATA;
2848 }
2849
2850 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2851 pldm_msgbuf_extract_range_field_format(
2852 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2853 pldm_msgbuf_extract_range_field_format(
2854 buf, pdr_value->range_field_format, pdr_value->normal_max);
2855 pldm_msgbuf_extract_range_field_format(
2856 buf, pdr_value->range_field_format, pdr_value->normal_min);
2857 pldm_msgbuf_extract_range_field_format(
2858 buf, pdr_value->range_field_format, pdr_value->rated_max);
2859 pldm_msgbuf_extract_range_field_format(
2860 buf, pdr_value->range_field_format, pdr_value->rated_min);
2861
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302862 rc = pldm_msgbuf_destroy_consumed(buf);
2863 if (rc) {
2864 return pldm_xlate_errno(rc);
2865 }
2866
2867 return PLDM_SUCCESS;
Thu Nguyend4878cd2023-11-09 10:18:33 +07002868}
Tal Yacobia6fa5552024-05-05 16:57:38 +03002869
Tal Yacobide67ab62024-05-30 22:36:50 +03002870LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002871int encode_get_state_effecter_states_req(uint8_t instance_id,
2872 uint16_t effecter_id,
2873 struct pldm_msg *msg,
2874 size_t payload_length)
2875{
2876 struct pldm_msgbuf _buf;
2877 struct pldm_msgbuf *buf = &_buf;
2878 int rc;
2879
2880 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002881 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002882 }
2883
2884 struct pldm_header_info header = { 0 };
2885 header.msg_type = PLDM_REQUEST;
2886 header.instance = instance_id;
2887 header.pldm_type = PLDM_PLATFORM;
2888 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2889
Tal Yacobif490a382024-05-31 09:57:36 +03002890 rc = pack_pldm_header_errno(&header, &msg->hdr);
2891 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002892 return rc;
2893 }
2894
Tal Yacobif490a382024-05-31 09:57:36 +03002895 rc = pldm_msgbuf_init_errno(buf,
2896 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2897 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002898 if (rc) {
2899 return rc;
2900 }
2901
2902 pldm_msgbuf_insert(buf, effecter_id);
2903
2904 return pldm_msgbuf_destroy_consumed(buf);
2905}
2906
Tal Yacobide67ab62024-05-30 22:36:50 +03002907LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002908int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
2909 size_t payload_length,
2910 uint16_t *effecter_id)
2911{
2912 struct pldm_msgbuf _buf;
2913 struct pldm_msgbuf *buf = &_buf;
2914 int rc;
2915
2916 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002917 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002918 }
2919
Tal Yacobif490a382024-05-31 09:57:36 +03002920 rc = pldm_msgbuf_init_errno(
2921 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2922 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002923 if (rc) {
2924 return rc;
2925 }
2926
2927 pldm_msgbuf_extract_p(buf, effecter_id);
2928
2929 return pldm_msgbuf_destroy_consumed(buf);
2930}
2931
Tal Yacobide67ab62024-05-30 22:36:50 +03002932LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002933int decode_get_state_effecter_states_resp(
2934 const struct pldm_msg *msg, size_t payload_length,
2935 struct pldm_get_state_effecter_states_resp *resp)
2936{
2937 struct pldm_msgbuf _buf;
2938 struct pldm_msgbuf *buf = &_buf;
2939 get_effecter_state_field *field;
2940 int rc;
2941 int i;
2942
2943 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002944 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002945 }
2946
Tal Yacobif490a382024-05-31 09:57:36 +03002947 rc = pldm_msgbuf_init_errno(
2948 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2949 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002950 if (rc) {
2951 return rc;
2952 }
2953
2954 rc = pldm_msgbuf_extract(buf, resp->completion_code);
2955 if (rc) {
2956 return rc;
2957 }
2958
2959 if (PLDM_SUCCESS != resp->completion_code) {
Tal Yacobif490a382024-05-31 09:57:36 +03002960 return 0;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002961 }
2962
2963 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
2964 if (rc) {
2965 return rc;
2966 }
2967
2968 uint8_t comp_effecter_count = resp->comp_effecter_count;
2969
2970 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2971 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002972 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002973 }
2974
2975 for (i = 0, field = resp->field; i < comp_effecter_count;
2976 i++, field++) {
2977 pldm_msgbuf_extract(buf, field->effecter_op_state);
2978 pldm_msgbuf_extract(buf, field->pending_state);
2979 pldm_msgbuf_extract(buf, field->present_state);
2980 }
2981
2982 return pldm_msgbuf_destroy_consumed(buf);
2983}
2984
Tal Yacobide67ab62024-05-30 22:36:50 +03002985LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002986int encode_get_state_effecter_states_resp(
2987 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
2988 struct pldm_msg *msg, size_t payload_length)
2989{
2990 struct pldm_msgbuf _buf;
2991 struct pldm_msgbuf *buf = &_buf;
2992 get_effecter_state_field *field;
2993 int rc;
2994 int i;
2995
2996 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002997 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002998 }
2999
3000 uint8_t comp_effecter_count = resp->comp_effecter_count;
3001
3002 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
3003 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03003004 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03003005 }
3006
3007 struct pldm_header_info header = { 0 };
3008 header.msg_type = PLDM_RESPONSE;
3009 header.instance = instance_id;
3010 header.pldm_type = PLDM_PLATFORM;
3011 header.command = PLDM_GET_STATE_EFFECTER_STATES;
3012
Tal Yacobif490a382024-05-31 09:57:36 +03003013 rc = pack_pldm_header_errno(&header, &msg->hdr);
3014 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03003015 return rc;
3016 }
3017
Tal Yacobif490a382024-05-31 09:57:36 +03003018 rc = pldm_msgbuf_init_errno(
3019 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3020 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003021 if (rc) {
3022 return rc;
3023 }
3024
3025 pldm_msgbuf_insert(buf, resp->completion_code);
3026 pldm_msgbuf_insert(buf, comp_effecter_count);
3027
3028 for (i = 0, field = resp->field; i < comp_effecter_count;
3029 i++, field++) {
3030 pldm_msgbuf_insert(buf, field->effecter_op_state);
3031 pldm_msgbuf_insert(buf, field->pending_state);
3032 pldm_msgbuf_insert(buf, field->present_state);
3033 }
3034
3035 return pldm_msgbuf_destroy_consumed(buf);
3036}
Thu Nguyendacfa352024-06-22 09:53:15 +00003037
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003038LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003039int decode_entity_auxiliary_names_pdr(
3040 const void *data, size_t data_length,
3041 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3042{
3043 struct pldm_msgbuf _buf;
3044 struct pldm_msgbuf *buf = &_buf;
3045 struct pldm_msgbuf _src;
3046 struct pldm_msgbuf *src = &_src;
3047 struct pldm_msgbuf _dst;
3048 struct pldm_msgbuf *dst = &_dst;
3049 size_t names_len = 0;
3050 void *names = NULL;
3051 int rc;
3052 int i;
3053
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003054 if (!data || !pdr) {
3055 return -EINVAL;
3056 }
3057
Thu Nguyendacfa352024-06-22 09:53:15 +00003058 /*
3059 * Alignment of auxiliary_name_data is an invariant as we statically assert
3060 * its behaviour in the header.
3061 */
3062 assert(!((uintptr_t)pdr->auxiliary_name_data &
3063 (alignof(pldm_utf16be) - 1)));
3064
3065 /* Reject any lengths that are obviously invalid */
3066 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3067 return -EINVAL;
3068 }
3069
3070 rc = pldm_msgbuf_init_errno(
3071 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3072 data_length);
3073 if (rc) {
3074 return rc;
3075 }
3076
3077 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr->hdr);
3078 if (rc) {
3079 return rc;
3080 }
3081
3082 rc = pldm_platform_pdr_hdr_validate(
3083 &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
3084 data_length);
3085 if (rc) {
3086 return rc;
3087 }
3088
3089 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3090 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3091 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3092 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3093 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3094 if (rc < 0) {
3095 return rc;
3096 }
3097
3098 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3099 if (rc < 0) {
3100 return rc;
3101 }
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003102 assert(names);
Thu Nguyendacfa352024-06-22 09:53:15 +00003103
3104 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3105
3106 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3107 pdr->auxiliary_name_data,
3108 pdr->auxiliary_name_data_size);
3109 if (rc < 0) {
3110 return rc;
3111 }
3112
3113 /*
3114 * Below we do two passes over the same region. This is to first pack the
3115 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3116 * to maintain appropriate alignment.
3117 */
3118
3119 /* Initialise for the first pass to extract the UTF16-BE name strings */
3120 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3121 if (rc < 0) {
3122 return rc;
3123 }
3124
3125 for (i = 0; i < pdr->name_string_count; i++) {
3126 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003127 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3128 if (rc) {
3129 return rc;
3130 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003131 }
3132
3133 rc = pldm_msgbuf_destroy_consumed(src);
3134 if (rc < 0) {
3135 return rc;
3136 }
3137
3138 /* Reinitialise for the second pass to extract the ASCII tag strings */
3139 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3140 if (rc < 0) {
3141 return rc;
3142 }
3143
3144 for (i = 0; i < pdr->name_string_count; i++) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003145 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3146 if (rc) {
3147 return rc;
3148 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003149 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3150 }
3151
3152 if ((rc = pldm_msgbuf_destroy(dst)) ||
3153 (rc = pldm_msgbuf_destroy(src)) ||
3154 (rc = pldm_msgbuf_destroy(buf))) {
3155 return rc;
3156 }
3157
3158 return 0;
3159}
3160
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003161LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003162int decode_pldm_entity_auxiliary_names_pdr_index(
3163 struct pldm_entity_auxiliary_names_pdr *pdr)
3164{
3165 struct pldm_msgbuf _buf;
3166 struct pldm_msgbuf *buf = &_buf;
3167 int rc;
3168 int i;
3169
3170 if (!pdr) {
3171 return -EINVAL;
3172 }
3173
3174 if (pdr->name_string_count == 0 && pdr->names) {
3175 return -EINVAL;
3176 }
3177
3178 if (pdr->name_string_count > 0 && !pdr->names) {
3179 return -EINVAL;
3180 }
3181
3182 if (pdr->name_string_count == 0) {
3183 return 0;
3184 }
3185
3186 /*
3187 * Minimum size is one NUL for each member of each entry
3188 *
3189 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3190 * states the following:
3191 *
3192 * > A null-terminated ISO646 ASCII string ...
3193 * >
3194 * > special value: null string = 0x0000 = unspecified.
3195 *
3196 * Until proven otherwise we will assume the "0x0000" is a
3197 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3198 * represented by a single byte.
3199 */
3200 rc = pldm_msgbuf_init_errno(
3201 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3202 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3203 if (rc) {
3204 return rc;
3205 }
3206
3207 for (i = 0; i < pdr->name_string_count; i++) {
3208 void *loc = NULL;
3209 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3210 pdr->names[i].name = loc;
3211 }
3212
3213 for (i = 0; i < pdr->name_string_count; i++) {
3214 void *loc = NULL;
3215 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3216 pdr->names[i].tag = loc;
3217 }
3218
3219 return pldm_msgbuf_destroy_consumed(buf);
3220}
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003221
Thu Nguyen3559aa12024-08-29 00:13:38 +00003222LIBPLDM_ABI_STABLE
Thu Nguyen02903032024-09-03 06:39:50 +00003223int decode_pldm_platform_cper_event(const void *event_data,
3224 size_t event_data_length,
3225 struct pldm_platform_cper_event *cper_event,
3226 size_t cper_event_length)
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003227{
3228 struct pldm_msgbuf _buf;
3229 struct pldm_msgbuf *buf = &_buf;
3230 int rc;
3231
3232 if (!cper_event || !event_data) {
3233 return -EINVAL;
3234 }
3235
3236 if (cper_event_length < sizeof(*cper_event)) {
3237 return -EINVAL;
3238 }
3239
3240 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3241 event_data, event_data_length);
3242 if (rc) {
3243 return rc;
3244 }
3245
3246 pldm_msgbuf_extract(buf, cper_event->format_version);
3247 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3248 if (rc) {
3249 return rc;
3250 }
3251 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3252 cper_event->format_type !=
3253 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3254 return -EPROTO;
3255 }
3256
3257 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3258 if (rc) {
3259 return rc;
3260 }
3261
3262 if (cper_event->event_data_length >
3263 (cper_event_length - sizeof(*cper_event))) {
3264 return -EOVERFLOW;
3265 }
3266
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003267 rc = pldm_msgbuf_extract_array_uint8(
3268 buf, cper_event->event_data_length, cper_event->event_data,
3269 cper_event_length - sizeof(*cper_event));
3270 if (rc) {
3271 return rc;
3272 }
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003273
3274 return pldm_msgbuf_destroy_consumed(buf);
3275}
3276
Thu Nguyen3559aa12024-08-29 00:13:38 +00003277LIBPLDM_ABI_STABLE
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003278uint8_t *
3279pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3280{
3281 return event->event_data;
3282}