blob: 1a2c962557d67283dfcf0403dd10c0f9fe8c9d45 [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 Jeffery9d2a1c62023-06-05 13:02:16 +093018LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093019int encode_state_effecter_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093020 struct pldm_state_effecter_pdr *const effecter,
21 const size_t allocation_size,
22 const struct state_effecter_possible_states *const possible_states,
23 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093024{
Andrew Jeffery9c766792022-08-10 23:12:49 +093025 size_t calculated_possible_states_size = 0;
26
Andrew Jefferyad33b992024-10-02 16:12:15 +093027 if (!effecter || !possible_states || !actual_size) {
28 return PLDM_ERROR;
29 }
30
Andrew Jeffery1be1d5e2024-11-07 10:43:44 +103031 if (SIZE_MAX - (sizeof(*effecter) - sizeof(effecter->possible_states)) <
32 possible_states_size) {
Andrew Jefferyad33b992024-10-02 16:12:15 +093033 return PLDM_ERROR;
34 }
35
36 if (allocation_size <
37 (sizeof(*effecter) - sizeof(effecter->possible_states)) +
38 possible_states_size) {
39 return PLDM_ERROR_INVALID_LENGTH;
40 }
41
42 // Encode possible states
43
Andrew Jeffery9c766792022-08-10 23:12:49 +093044 {
45 char *states_ptr = (char *)possible_states;
46 char *const begin_states_ptr = states_ptr;
47
48 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
49 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093050 (struct state_effecter_possible_states *)
51 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093052
53 HTOLE16(states->state_set_id);
54
55 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093056 (sizeof(*states) - sizeof(states->states) +
57 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093058 }
59
60 calculated_possible_states_size = states_ptr - begin_states_ptr;
61 }
62
63 // Check lengths
64
65 if (possible_states_size != calculated_possible_states_size) {
66 *actual_size = 0;
67 return PLDM_ERROR;
68 }
69
70 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093071 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
72 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093073
Andrew Jeffery9c766792022-08-10 23:12:49 +093074 // Encode rest of PDR
75
76 effecter->hdr.version = 1;
77 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
78 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
79
80 memcpy(effecter->possible_states, possible_states,
81 possible_states_size);
82
83 // Convert effecter PDR body
84 HTOLE16(effecter->terminus_handle);
85 HTOLE16(effecter->effecter_id);
86 HTOLE16(effecter->entity_type);
87 HTOLE16(effecter->entity_instance);
88 HTOLE16(effecter->container_id);
89 HTOLE16(effecter->effecter_semantic_id);
90
91 // Convert header
92 HTOLE32(effecter->hdr.record_handle);
93 HTOLE16(effecter->hdr.record_change_num);
94 HTOLE16(effecter->hdr.length);
95
96 return PLDM_SUCCESS;
97}
98
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093099LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930100int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930101 struct pldm_state_sensor_pdr *const sensor,
102 const size_t allocation_size,
103 const struct state_sensor_possible_states *const possible_states,
104 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930105{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930106 size_t calculated_possible_states_size = 0;
107
Andrew Jefferybb50a592024-09-26 21:59:44 +0930108 if (!sensor || !possible_states || !actual_size) {
109 return PLDM_ERROR;
110 }
111
112 if (SIZE_MAX - (sizeof(*sensor) - sizeof(sensor->possible_states)) <
113 possible_states_size) {
114 return PLDM_ERROR;
115 }
116
117 if (allocation_size <
118 (sizeof(*sensor) - sizeof(sensor->possible_states) +
119 possible_states_size)) {
120 return PLDM_ERROR_INVALID_LENGTH;
121 }
122
Andrew Jeffery9c766792022-08-10 23:12:49 +0930123 {
Andrew Jefferybb50a592024-09-26 21:59:44 +0930124 // Encode possible states
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930125 char *states_ptr = (char *)possible_states;
126 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930127
128 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
129 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930130 (struct state_sensor_possible_states *)
131 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930132
133 HTOLE16(states->state_set_id);
134
135 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930136 (sizeof(*states) - sizeof(states->states) +
137 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930138 }
139
140 calculated_possible_states_size = states_ptr - begin_states_ptr;
141 }
142
143 // Check lengths
144
145 if (possible_states_size != calculated_possible_states_size) {
146 *actual_size = 0;
147 return PLDM_ERROR;
148 }
149
150 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
151 possible_states_size - sizeof(sensor->possible_states));
152
Andrew Jeffery9c766792022-08-10 23:12:49 +0930153 // Encode rest of PDR
154
155 sensor->hdr.version = 1;
156 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
157 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
158
159 memcpy(sensor->possible_states, possible_states, possible_states_size);
160
161 // Convert sensor PDR body
162 HTOLE16(sensor->terminus_handle);
163 HTOLE16(sensor->sensor_id);
164 HTOLE16(sensor->entity_type);
165 HTOLE16(sensor->entity_instance);
166 HTOLE16(sensor->container_id);
167
168 // Convert header
169 HTOLE32(sensor->hdr.record_handle);
170 HTOLE16(sensor->hdr.record_change_num);
171 HTOLE16(sensor->hdr.length);
172
173 return PLDM_SUCCESS;
174}
175
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930176LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930177int encode_set_state_effecter_states_resp(uint8_t instance_id,
178 uint8_t completion_code,
179 struct pldm_msg *msg)
180{
181 if (msg == NULL) {
182 return PLDM_ERROR_INVALID_DATA;
183 }
184
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930185 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930186 header.msg_type = PLDM_RESPONSE;
187 header.instance = instance_id;
188 header.pldm_type = PLDM_PLATFORM;
189 header.command = PLDM_SET_STATE_EFFECTER_STATES;
190
191 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
192 if (rc != PLDM_SUCCESS) {
193 return rc;
194 }
195
196 msg->payload[0] = completion_code;
197
198 return PLDM_SUCCESS;
199}
200
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930201LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930202int encode_set_state_effecter_states_req(uint8_t instance_id,
203 uint16_t effecter_id,
204 uint8_t comp_effecter_count,
205 set_effecter_state_field *field,
206 struct pldm_msg *msg)
207{
208 if (msg == NULL) {
209 return PLDM_ERROR_INVALID_DATA;
210 }
211
212 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
213 field == NULL) {
214 return PLDM_ERROR_INVALID_DATA;
215 }
216
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930217 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930218 header.msg_type = PLDM_REQUEST;
219 header.instance = instance_id;
220 header.pldm_type = PLDM_PLATFORM;
221 header.command = PLDM_SET_STATE_EFFECTER_STATES;
222
223 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
224 if (rc != PLDM_SUCCESS) {
225 return rc;
226 }
227
228 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930229 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930230 effecter_id = htole16(effecter_id);
231 request->effecter_id = effecter_id;
232 request->comp_effecter_count = comp_effecter_count;
233 memcpy(request->field, field,
234 (sizeof(set_effecter_state_field) * comp_effecter_count));
235
236 return PLDM_SUCCESS;
237}
238
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930239LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930240int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
241 size_t payload_length,
242 uint8_t *completion_code)
243{
244 if (msg == NULL || completion_code == NULL) {
245 return PLDM_ERROR_INVALID_DATA;
246 }
247
248 *completion_code = msg->payload[0];
249 if (PLDM_SUCCESS != *completion_code) {
250 return PLDM_SUCCESS;
251 }
252
253 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
254 return PLDM_ERROR_INVALID_LENGTH;
255 }
256
257 return PLDM_SUCCESS;
258}
259
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930260#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930261LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930262int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
263 size_t payload_length,
264 uint16_t *effecter_id,
265 uint8_t *comp_effecter_count,
266 set_effecter_state_field *field)
267{
Andrew Jefferya1896962025-03-03 21:41:25 +1030268 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930269 int rc;
270 int i;
271
Andrew Jeffery9c766792022-08-10 23:12:49 +0930272 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
273 field == NULL) {
274 return PLDM_ERROR_INVALID_DATA;
275 }
276
277 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
278 return PLDM_ERROR_INVALID_LENGTH;
279 }
280
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930281 rc = pldm_msgbuf_init_errno(buf,
282 PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
283 msg->payload, payload_length);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930284 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930285 return pldm_xlate_errno(rc);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930286 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930287
Andrew Jeffery66c77232024-04-24 11:42:02 +0930288 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jefferya1896962025-03-03 21:41:25 +1030289 rc = pldm_msgbuf_extract_p(buf, comp_effecter_count);
290 if (rc) {
291 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
292 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930293
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930294 if (*comp_effecter_count > 8) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030295 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930296 }
297
298 for (i = 0; i < *comp_effecter_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930299 pldm_msgbuf_extract(buf, field[i].set_request);
300 pldm_msgbuf_extract(buf, field[i].effecter_state);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930301 }
302
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030303 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930304 if (rc) {
305 return pldm_xlate_errno(rc);
306 }
307
308 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930309}
310
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930311LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930312int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
313 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
314 uint8_t *transfer_op_flag, uint16_t *request_cnt,
315 uint16_t *record_chg_num)
316{
Andrew Jefferya1896962025-03-03 21:41:25 +1030317 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930318 int rc;
319
Andrew Jeffery9c766792022-08-10 23:12:49 +0930320 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
321 transfer_op_flag == NULL || request_cnt == NULL ||
322 record_chg_num == NULL) {
323 return PLDM_ERROR_INVALID_DATA;
324 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930325
Andrew Jeffery9c766792022-08-10 23:12:49 +0930326 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
327 return PLDM_ERROR_INVALID_LENGTH;
328 }
329
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930330 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
331 payload_length);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930332 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930333 return pldm_xlate_errno(rc);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930334 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930335
Andrew Jeffery66c77232024-04-24 11:42:02 +0930336 pldm_msgbuf_extract_p(buf, record_hndl);
337 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
338 pldm_msgbuf_extract_p(buf, transfer_op_flag);
339 pldm_msgbuf_extract_p(buf, request_cnt);
340 pldm_msgbuf_extract_p(buf, record_chg_num);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930341
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030342 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930343 if (rc) {
344 return pldm_xlate_errno(rc);
345 }
346
347 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930348}
349
Andrew Jeffery36324f62024-09-25 13:41:41 +0930350LIBPLDM_ABI_DEPRECATED_UNSAFE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930351int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
352 uint32_t next_record_hndl,
353 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
354 uint16_t resp_cnt, const uint8_t *record_data,
355 uint8_t transfer_crc, struct pldm_msg *msg)
356{
357 if (msg == NULL) {
358 return PLDM_ERROR_INVALID_DATA;
359 }
360
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930361 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930362 header.msg_type = PLDM_RESPONSE;
363 header.instance = instance_id;
364 header.pldm_type = PLDM_PLATFORM;
365 header.command = PLDM_GET_PDR;
366
367 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
368 if (rc != PLDM_SUCCESS) {
369 return rc;
370 }
371
372 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930373 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930374 response->completion_code = completion_code;
375
376 if (response->completion_code == PLDM_SUCCESS) {
377 response->next_record_handle = htole32(next_record_hndl);
378 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930379 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930380 response->transfer_flag = transfer_flag;
381 response->response_count = htole16(resp_cnt);
382 if (record_data != NULL && resp_cnt > 0) {
383 memcpy(response->record_data, record_data, resp_cnt);
384 }
385 if (transfer_flag == PLDM_END) {
386 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930387 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
388 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930389 *dst = transfer_crc;
390 }
391 }
392
393 return PLDM_SUCCESS;
394}
395
Vishnu Santhosh48b0f802025-05-19 20:30:15 +0530396LIBPLDM_ABI_TESTING
397int encode_get_pdr_repository_info_req(uint8_t instance_id,
398 struct pldm_msg *msg,
399 size_t payload_length LIBPLDM_CC_UNUSED)
400{
401 if (!msg) {
402 return -EINVAL;
403 }
404
405 struct pldm_header_info header = { 0 };
406 header.msg_type = PLDM_REQUEST;
407 header.instance = instance_id;
408 header.pldm_type = PLDM_PLATFORM;
409 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
410
411 return pack_pldm_header_errno(&header, &(msg->hdr));
412}
413
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930414LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930415int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930416 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
417 const uint8_t *update_time, const uint8_t *oem_update_time,
418 uint32_t record_count, uint32_t repository_size,
419 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
420 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930421{
422 if (msg == NULL) {
423 return PLDM_ERROR_INVALID_DATA;
424 }
425
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930426 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930427 header.msg_type = PLDM_RESPONSE;
428 header.instance = instance_id;
429 header.pldm_type = PLDM_PLATFORM;
430 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
431
432 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
433 if (rc != PLDM_SUCCESS) {
434 return rc;
435 }
436
437 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930438 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930439 response->completion_code = completion_code;
440
441 if (response->completion_code == PLDM_SUCCESS) {
442 response->repository_state = repository_state;
443 if (update_time != NULL) {
444 memcpy(response->update_time, update_time,
445 PLDM_TIMESTAMP104_SIZE);
446 }
447 if (oem_update_time != NULL) {
448 memcpy(response->oem_update_time, oem_update_time,
449 PLDM_TIMESTAMP104_SIZE);
450 }
451 response->record_count = htole32(record_count);
452 response->repository_size = htole32(repository_size);
453 response->largest_record_size = htole32(largest_record_size);
454 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930455 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930456 }
457
458 return PLDM_SUCCESS;
459}
460
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000461LIBPLDM_ABI_DEPRECATED
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800462int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930463 const struct pldm_msg *msg, size_t payload_length,
464 uint8_t *completion_code, uint8_t *repository_state,
465 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
466 uint32_t *repository_size, uint32_t *largest_record_size,
467 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800468{
Andrew Jefferya1896962025-03-03 21:41:25 +1030469 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930470 int rc;
471
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800472 if (msg == NULL || completion_code == NULL ||
473 repository_state == NULL || update_time == NULL ||
474 oem_update_time == NULL || record_count == NULL ||
475 repository_size == NULL || largest_record_size == NULL ||
476 data_transfer_handle_timeout == NULL) {
477 return PLDM_ERROR_INVALID_DATA;
478 }
479
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930480 rc = pldm_msgbuf_init_errno(buf,
481 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
482 msg->payload, payload_length);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930483 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930484 return pldm_xlate_errno(rc);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930485 }
486
Andrew Jefferya1896962025-03-03 21:41:25 +1030487 rc = pldm_msgbuf_extract_p(buf, completion_code);
488 if (rc) {
489 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
490 }
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800491 if (PLDM_SUCCESS != *completion_code) {
492 return PLDM_SUCCESS;
493 }
494
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930495 rc = pldm_msgbuf_extract_p(buf, repository_state);
496 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030497 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930498 }
499
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800500 if (*repository_state > PLDM_FAILED) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030501 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800502 }
503
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000504 /* NOTE: Memory safety */
505 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
506 PLDM_TIMESTAMP104_SIZE);
507 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030508 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000509 }
510
511 /* NOTE: Memory safety */
512 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
513 oem_update_time, PLDM_TIMESTAMP104_SIZE);
514 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030515 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000516 }
517
Andrew Jeffery66c77232024-04-24 11:42:02 +0930518 pldm_msgbuf_extract_p(buf, record_count);
519 pldm_msgbuf_extract_p(buf, repository_size);
520 pldm_msgbuf_extract_p(buf, largest_record_size);
521 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800522
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030523 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930524 if (rc) {
525 return pldm_xlate_errno(rc);
526 }
527
528 return PLDM_SUCCESS;
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800529}
530
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000531LIBPLDM_ABI_TESTING
532int decode_get_pdr_repository_info_resp_safe(
533 const struct pldm_msg *msg, size_t payload_length,
534 struct pldm_pdr_repository_info_resp *resp)
535{
Andrew Jefferya1896962025-03-03 21:41:25 +1030536 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000537 int rc;
538
539 if (msg == NULL || resp == NULL) {
540 return -EINVAL;
541 }
542
543 rc = pldm_msg_has_error(msg, payload_length);
544 if (rc) {
545 resp->completion_code = rc;
546 return 0;
547 }
548
549 rc = pldm_msgbuf_init_errno(buf,
550 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
551 msg->payload, payload_length);
552 if (rc) {
553 return rc;
554 }
555
556 rc = pldm_msgbuf_extract(buf, resp->completion_code);
557 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030558 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000559 }
560
561 pldm_msgbuf_extract(buf, resp->repository_state);
562
563 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
564 resp->update_time,
565 sizeof(resp->update_time));
566 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030567 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000568 }
569
570 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
571 resp->oem_update_time,
572 sizeof(resp->oem_update_time));
573 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030574 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000575 }
576
577 pldm_msgbuf_extract(buf, resp->record_count);
578 pldm_msgbuf_extract(buf, resp->repository_size);
579 pldm_msgbuf_extract(buf, resp->largest_record_size);
580 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
581
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030582 return pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000583}
584
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930585LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930586int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
587 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
588 uint16_t request_cnt, uint16_t record_chg_num,
589 struct pldm_msg *msg, size_t payload_length)
590{
591 if (msg == NULL) {
592 return PLDM_ERROR_INVALID_DATA;
593 }
594
595 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
596 return PLDM_ERROR_INVALID_LENGTH;
597 }
598
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930599 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930600 header.msg_type = PLDM_REQUEST;
601 header.instance = instance_id;
602 header.pldm_type = PLDM_PLATFORM;
603 header.command = PLDM_GET_PDR;
604
605 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
606 if (rc != PLDM_SUCCESS) {
607 return rc;
608 }
609
610 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930611 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930612 request->record_handle = htole32(record_hndl);
613 request->data_transfer_handle = htole32(data_transfer_hndl);
614 request->transfer_op_flag = transfer_op_flag;
615 request->request_count = htole16(request_cnt);
616 request->record_change_number = htole16(record_chg_num);
617
618 return PLDM_SUCCESS;
619}
620
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000621LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930622int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
623 uint8_t *completion_code, uint32_t *next_record_hndl,
624 uint32_t *next_data_transfer_hndl,
625 uint8_t *transfer_flag, uint16_t *resp_cnt,
626 uint8_t *record_data, size_t record_data_length,
627 uint8_t *transfer_crc)
628{
Andrew Jefferya1896962025-03-03 21:41:25 +1030629 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930630 int rc;
631
Andrew Jeffery9c766792022-08-10 23:12:49 +0930632 if (msg == NULL || completion_code == NULL ||
633 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
634 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
635 return PLDM_ERROR_INVALID_DATA;
636 }
637
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930638 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
639 msg->payload, payload_length);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930640 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930641 return pldm_xlate_errno(rc);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930642 }
643
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930644 rc = pldm_msgbuf_extract_p(buf, completion_code);
645 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030646 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930647 }
648
Andrew Jeffery9c766792022-08-10 23:12:49 +0930649 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030650 return pldm_msgbuf_complete(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930651 }
652
Andrew Jeffery66c77232024-04-24 11:42:02 +0930653 pldm_msgbuf_extract_p(buf, next_record_hndl);
654 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
655 pldm_msgbuf_extract_p(buf, transfer_flag);
656 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930657 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030658 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930659 }
660
661 if (*resp_cnt > 0 && record_data != NULL) {
662 if (record_data_length < *resp_cnt) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030663 return pldm_msgbuf_discard(buf,
664 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930665 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000666 /* NOTE: Memory safety */
667 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
668 *resp_cnt);
669 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030670 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000671 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930672 }
673
674 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930675 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930676 }
677
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030678 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930679 if (rc) {
680 return pldm_xlate_errno(rc);
681 }
682
683 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930684}
685
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000686LIBPLDM_ABI_TESTING
687int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
688 struct pldm_get_pdr_resp *resp, size_t resp_len,
689 uint8_t *transfer_crc)
690{
Andrew Jefferya1896962025-03-03 21:41:25 +1030691 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000692 int rc;
693
694 if (msg == NULL || resp == NULL || transfer_crc == NULL) {
695 return -EINVAL;
696 }
697
698 rc = pldm_msg_has_error(msg, payload_length);
699 if (rc) {
700 resp->completion_code = rc;
701 return 0;
702 }
703
704 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
705 msg->payload, payload_length);
706 if (rc) {
707 return rc;
708 }
709
710 pldm_msgbuf_extract(buf, resp->completion_code);
711 pldm_msgbuf_extract(buf, resp->next_record_handle);
712 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
713
714 rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
715 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030716 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000717 }
718
719 rc = pldm_msgbuf_extract(buf, resp->response_count);
720 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030721 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000722 }
723
724 rc = pldm_msgbuf_extract_array(
725 buf, resp->response_count, resp->record_data,
726 resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
727 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030728 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000729 }
730
731 if (resp->transfer_flag == PLDM_END) {
732 pldm_msgbuf_extract_p(buf, transfer_crc);
733 }
734
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030735 return pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000736}
737
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930738LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930739int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
740 size_t payload_length,
741 uint16_t *effecter_id,
742 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930743 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930744{
Andrew Jefferya1896962025-03-03 21:41:25 +1030745 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930746 int rc;
747
Andrew Jeffery9c766792022-08-10 23:12:49 +0930748 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
749 effecter_value == NULL) {
750 return PLDM_ERROR_INVALID_DATA;
751 }
752
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930753 rc = pldm_msgbuf_init_errno(
754 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
755 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930756 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930757 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930758 }
759
Andrew Jeffery66c77232024-04-24 11:42:02 +0930760 pldm_msgbuf_extract_p(buf, effecter_id);
761 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930762 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030763 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930764 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930765
766 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030767 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930768 }
769
Andrew Jeffery3884c442023-04-12 11:13:24 +0930770 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
771 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930772
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030773 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930774 if (rc) {
775 return pldm_xlate_errno(rc);
776 }
777
778 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930779}
780
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930781LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930782int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
783 uint8_t completion_code,
784 struct pldm_msg *msg,
785 size_t payload_length)
786{
787 if (msg == NULL) {
788 return PLDM_ERROR_INVALID_DATA;
789 }
790
791 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
792 return PLDM_ERROR_INVALID_LENGTH;
793 }
794
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930795 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930796 header.msg_type = PLDM_RESPONSE;
797 header.instance = instance_id;
798 header.pldm_type = PLDM_PLATFORM;
799 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
800
801 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
802 if (rc != PLDM_SUCCESS) {
803 return rc;
804 }
805
806 msg->payload[0] = completion_code;
807
808 return rc;
809}
810
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930811LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930812int encode_set_numeric_effecter_value_req(uint8_t instance_id,
813 uint16_t effecter_id,
814 uint8_t effecter_data_size,
815 const uint8_t *effecter_value,
816 struct pldm_msg *msg,
817 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930818{
819 if (msg == NULL || effecter_value == NULL) {
820 return PLDM_ERROR_INVALID_DATA;
821 }
822
823 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
824 return PLDM_ERROR_INVALID_DATA;
825 }
826
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930827 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930828 header.msg_type = PLDM_REQUEST;
829 header.instance = instance_id;
830 header.pldm_type = PLDM_PLATFORM;
831 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
832
833 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
834 if (rc != PLDM_SUCCESS) {
835 return rc;
836 }
837
838 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930839 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930840 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
841 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
842 if (payload_length !=
843 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
844 return PLDM_ERROR_INVALID_LENGTH;
845 }
846 request->effecter_value[0] = *effecter_value;
847 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
848 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
849 if (payload_length !=
850 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
851 return PLDM_ERROR_INVALID_LENGTH;
852 }
853
854 uint16_t val = *(uint16_t *)(effecter_value);
855 val = htole16(val);
856 memcpy(request->effecter_value, &val, sizeof(uint16_t));
857
858 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
859 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
860 if (payload_length !=
861 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
862 return PLDM_ERROR_INVALID_LENGTH;
863 }
864
865 uint32_t val = *(uint32_t *)(effecter_value);
866 val = htole32(val);
867 memcpy(request->effecter_value, &val, sizeof(uint32_t));
868 }
869
870 request->effecter_id = htole16(effecter_id);
871 request->effecter_data_size = effecter_data_size;
872
873 return PLDM_SUCCESS;
874}
875
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930876LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930877int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
878 size_t payload_length,
879 uint8_t *completion_code)
880{
881 if (msg == NULL || completion_code == NULL) {
882 return PLDM_ERROR_INVALID_DATA;
883 }
884
885 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
886 return PLDM_ERROR_INVALID_LENGTH;
887 }
888
889 *completion_code = msg->payload[0];
890
891 return PLDM_SUCCESS;
892}
893
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930894LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930895int encode_get_state_sensor_readings_resp(uint8_t instance_id,
896 uint8_t completion_code,
897 uint8_t comp_sensor_count,
898 get_sensor_state_field *field,
899 struct pldm_msg *msg)
900{
901 if (msg == NULL) {
902 return PLDM_ERROR_INVALID_DATA;
903 }
904
905 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
906 return PLDM_ERROR_INVALID_DATA;
907 }
908
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930909 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930910 header.msg_type = PLDM_RESPONSE;
911 header.instance = instance_id;
912 header.pldm_type = PLDM_PLATFORM;
913 header.command = PLDM_GET_STATE_SENSOR_READINGS;
914
915 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
916 if (rc != PLDM_SUCCESS) {
917 return rc;
918 }
919
920 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930921 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930922
923 response->completion_code = completion_code;
924 response->comp_sensor_count = comp_sensor_count;
925 memcpy(response->field, field,
926 (sizeof(get_sensor_state_field) * comp_sensor_count));
927
928 return PLDM_SUCCESS;
929}
930
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930931LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930932int encode_get_state_sensor_readings_req(uint8_t instance_id,
933 uint16_t sensor_id,
934 bitfield8_t sensor_rearm,
935 uint8_t reserved, struct pldm_msg *msg)
936{
937 if (msg == NULL) {
938 return PLDM_ERROR_INVALID_DATA;
939 }
940
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930941 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930942 header.msg_type = PLDM_REQUEST;
943 header.instance = instance_id;
944 header.pldm_type = PLDM_PLATFORM;
945 header.command = PLDM_GET_STATE_SENSOR_READINGS;
946
947 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
948 if (rc != PLDM_SUCCESS) {
949 return rc;
950 }
951
952 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930953 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930954
955 request->sensor_id = htole16(sensor_id);
956 request->reserved = reserved;
957 request->sensor_rearm = sensor_rearm;
958
959 return PLDM_SUCCESS;
960}
961
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930962LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930963int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
964 size_t payload_length,
965 uint8_t *completion_code,
966 uint8_t *comp_sensor_count,
967 get_sensor_state_field *field)
968{
Andrew Jefferya1896962025-03-03 21:41:25 +1030969 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930970 uint8_t i;
971 int rc;
972
Andrew Jeffery9c766792022-08-10 23:12:49 +0930973 if (msg == NULL || completion_code == NULL ||
974 comp_sensor_count == NULL || field == NULL) {
975 return PLDM_ERROR_INVALID_DATA;
976 }
977
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930978 rc = pldm_msgbuf_init_errno(
979 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
980 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930981 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930982 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930983 }
984
Andrew Jeffery66c77232024-04-24 11:42:02 +0930985 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930986 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030987 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930988 }
989
Andrew Jeffery9c766792022-08-10 23:12:49 +0930990 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030991 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930992 }
993
Andrew Jeffery66c77232024-04-24 11:42:02 +0930994 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930995 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030996 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930997 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930998
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930999 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301000 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301001 }
1002
Andrew Jefferyb0e22a72023-04-12 23:14:36 +09301003 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301004 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
1005 pldm_msgbuf_extract(buf, field[i].present_state);
1006 pldm_msgbuf_extract(buf, field[i].previous_state);
1007 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301008 }
1009
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301010 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301011 if (rc) {
1012 return pldm_xlate_errno(rc);
1013 }
1014
1015 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301016}
1017
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301018LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301019int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
1020 size_t payload_length,
1021 uint16_t *sensor_id,
1022 bitfield8_t *sensor_rearm,
1023 uint8_t *reserved)
1024{
Andrew Jefferya1896962025-03-03 21:41:25 +10301025 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301026 int rc;
1027
Andrew Jeffery9c766792022-08-10 23:12:49 +09301028 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
1029 return PLDM_ERROR_INVALID_DATA;
1030 }
1031
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301032 rc = pldm_msgbuf_init_errno(buf,
1033 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
1034 msg->payload, payload_length);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301035 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301036 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301037 }
1038
Andrew Jeffery66c77232024-04-24 11:42:02 +09301039 pldm_msgbuf_extract_p(buf, sensor_id);
1040 pldm_msgbuf_extract(buf, sensor_rearm->byte);
1041 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301042
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301043 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301044 if (rc) {
1045 return pldm_xlate_errno(rc);
1046 }
1047
1048 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301049}
1050
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301051LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301052int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301053 struct pldm_sensor_event_data *const event_data,
1054 const size_t event_data_size, const uint16_t sensor_id,
1055 const enum sensor_event_class_states sensor_event_class,
1056 const uint8_t sensor_offset, const uint8_t event_state,
1057 const uint8_t previous_event_state,
1058 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301059{
1060 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301061 (sizeof(*event_data) - sizeof(event_data->event_class) +
1062 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301063
1064 if (!event_data) {
1065 return PLDM_SUCCESS;
1066 }
1067
1068 if (event_data_size < *actual_event_data_size) {
1069 *actual_event_data_size = 0;
1070 return PLDM_ERROR_INVALID_LENGTH;
1071 }
1072
1073 event_data->sensor_id = htole16(sensor_id);
1074 event_data->sensor_event_class_type = sensor_event_class;
1075
1076 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301077 (struct pldm_sensor_event_state_sensor_state *)
1078 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301079
1080 state_data->sensor_offset = sensor_offset;
1081 state_data->event_state = event_state;
1082 state_data->previous_event_state = previous_event_state;
1083
1084 return PLDM_SUCCESS;
1085}
1086
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301087LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301088int decode_platform_event_message_req(const struct pldm_msg *msg,
1089 size_t payload_length,
1090 uint8_t *format_version, uint8_t *tid,
1091 uint8_t *event_class,
1092 size_t *event_data_offset)
1093{
Andrew Jefferya1896962025-03-03 21:41:25 +10301094 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301095 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301096
1097 if (msg == NULL || format_version == NULL || tid == NULL ||
1098 event_class == NULL || event_data_offset == NULL) {
1099 return PLDM_ERROR_INVALID_DATA;
1100 }
1101
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301102 rc = pldm_msgbuf_init_errno(buf,
1103 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
1104 msg->payload, payload_length);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301105 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301106 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301107 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301108
Andrew Jeffery66c77232024-04-24 11:42:02 +09301109 pldm_msgbuf_extract_p(buf, format_version);
1110 pldm_msgbuf_extract_p(buf, tid);
1111 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301112
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301113 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301114 if (rc) {
1115 return pldm_xlate_errno(rc);
1116 }
1117
Andrew Jeffery9c766792022-08-10 23:12:49 +09301118 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301119 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301120
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301121 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301122}
1123
Thu Nguyen387b10f2024-09-24 11:33:16 +00001124static int pldm_platform_poll_for_platform_event_message_validate(
1125 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1126{
1127 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1128 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1129 ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1130 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1131 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
Thu Nguyen9e16b182024-10-01 03:12:16 +00001132 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1133 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1134 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
Thu Nguyen387b10f2024-09-24 11:33:16 +00001135 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1136 return -EPROTO;
1137 }
1138
1139 return 0;
1140}
1141
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301142LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001143int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301144 const struct pldm_msg *msg, size_t payload_length,
1145 uint8_t *format_version, uint8_t *transfer_operation_flag,
1146 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001147{
Andrew Jefferya1896962025-03-03 21:41:25 +10301148 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001149 int rc;
1150
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001151 if (msg == NULL || format_version == NULL ||
1152 transfer_operation_flag == NULL || data_transfer_handle == NULL ||
1153 event_id_to_acknowledge == NULL) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001154 return PLDM_ERROR_INVALID_DATA;
1155 }
1156
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301157 rc = pldm_msgbuf_init_errno(
1158 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
1159 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001160 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301161 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001162 }
1163
Andrew Jeffery66c77232024-04-24 11:42:02 +09301164 pldm_msgbuf_extract_p(buf, format_version);
1165 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001166 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301167 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001168 }
1169 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301170 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001171 }
1172
Andrew Jeffery66c77232024-04-24 11:42:02 +09301173 pldm_msgbuf_extract_p(buf, data_transfer_handle);
1174 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001175 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301176 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001177 }
1178
Thu Nguyen387b10f2024-09-24 11:33:16 +00001179 rc = pldm_platform_poll_for_platform_event_message_validate(
1180 *transfer_operation_flag, *event_id_to_acknowledge);
1181 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301182 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001183 }
1184
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301185 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301186 if (rc) {
1187 return pldm_xlate_errno(rc);
1188 }
1189
1190 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001191}
1192
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301193LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301194int encode_platform_event_message_resp(uint8_t instance_id,
1195 uint8_t completion_code,
1196 uint8_t platform_event_status,
1197 struct pldm_msg *msg)
1198{
1199 if (msg == NULL) {
1200 return PLDM_ERROR_INVALID_DATA;
1201 }
1202
1203 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1204 return PLDM_ERROR_INVALID_DATA;
1205 }
1206
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301207 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301208 header.msg_type = PLDM_RESPONSE;
1209 header.instance = instance_id;
1210 header.pldm_type = PLDM_PLATFORM;
1211 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1212
1213 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1214 if (rc != PLDM_SUCCESS) {
1215 return rc;
1216 }
1217
1218 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301219 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301220 response->completion_code = completion_code;
1221 response->platform_event_status = platform_event_status;
1222
1223 return PLDM_SUCCESS;
1224}
1225
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301226LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001227int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301228 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1229 uint16_t event_id, uint32_t next_data_transfer_handle,
1230 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1231 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1232 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001233{
Andrew Jefferya1896962025-03-03 21:41:25 +10301234 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001235 int rc;
1236
1237 if (!msg) {
1238 return PLDM_ERROR_INVALID_DATA;
1239 }
1240
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301241 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001242 header.msg_type = PLDM_RESPONSE;
1243 header.instance = instance_id;
1244 header.pldm_type = PLDM_PLATFORM;
1245 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1246
1247 rc = pack_pldm_header(&header, &(msg->hdr));
1248 if (rc != PLDM_SUCCESS) {
1249 return rc;
1250 }
1251
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301252 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301253 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1254 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001255 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301256 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001257 }
1258
1259 pldm_msgbuf_insert(buf, completion_code);
1260 pldm_msgbuf_insert(buf, tid);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301261 rc = pldm_msgbuf_insert(buf, event_id);
1262 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301263 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301264 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001265
1266 if (event_id == 0xffff || event_id == 0x0000) {
1267 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1268 payload_length) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301269 return pldm_msgbuf_discard(buf,
1270 PLDM_ERROR_INVALID_LENGTH);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001271 }
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301272
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301273 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301274 if (rc) {
1275 return pldm_xlate_errno(rc);
1276 }
1277
1278 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001279 }
1280
1281 if ((event_data == NULL) && (event_data_size > 0)) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301282 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001283 }
1284
1285 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1286 pldm_msgbuf_insert(buf, transfer_flag);
1287 pldm_msgbuf_insert(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301288 rc = pldm_msgbuf_insert(buf, event_data_size);
1289 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301290 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301291 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001292
1293 if ((event_data_size > 0) && event_data) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001294 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
1295 event_data_size);
1296 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301297 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001298 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001299 }
1300
1301 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1302 pldm_msgbuf_insert(buf, checksum);
1303 }
1304
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301305 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301306 if (rc) {
1307 return pldm_xlate_errno(rc);
1308 }
1309
1310 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001311}
1312
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301313LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301314int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301315 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1316 uint8_t event_class, const uint8_t *event_data,
1317 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301318
1319{
1320 if (format_version != 1) {
1321 return PLDM_ERROR_INVALID_DATA;
1322 }
1323
1324 if (msg == NULL || event_data == NULL) {
1325 return PLDM_ERROR_INVALID_DATA;
1326 }
1327
1328 if (event_data_length == 0) {
1329 return PLDM_ERROR_INVALID_DATA;
1330 }
1331
Andrew Jeffery225530a2024-09-25 13:11:43 +09301332 if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1333 event_data_length) {
1334 return PLDM_ERROR_INVALID_LENGTH;
1335 }
1336
Andrew Jeffery9c766792022-08-10 23:12:49 +09301337 if (payload_length !=
1338 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1339 return PLDM_ERROR_INVALID_LENGTH;
1340 }
1341
John Chungb43a7782024-09-26 22:04:27 +08001342 if (event_class > PLDM_CPER_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001343 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301344 return PLDM_ERROR_INVALID_DATA;
1345 }
1346
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301347 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301348 header.msg_type = PLDM_REQUEST;
1349 header.instance = instance_id;
1350 header.pldm_type = PLDM_PLATFORM;
1351 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1352
1353 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1354 if (rc != PLDM_SUCCESS) {
1355 return rc;
1356 }
1357
1358 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301359 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301360 request->format_version = format_version;
1361 request->tid = tid;
1362 request->event_class = event_class;
1363 memcpy(request->event_data, event_data, event_data_length);
1364
1365 return PLDM_SUCCESS;
1366}
1367
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301368LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301369int decode_platform_event_message_resp(const struct pldm_msg *msg,
1370 size_t payload_length,
1371 uint8_t *completion_code,
1372 uint8_t *platform_event_status)
1373{
Andrew Jefferya1896962025-03-03 21:41:25 +10301374 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferye5011772023-04-13 12:06:22 +09301375 int rc;
1376
Andrew Jeffery9c766792022-08-10 23:12:49 +09301377 if (msg == NULL || completion_code == NULL ||
1378 platform_event_status == NULL) {
1379 return PLDM_ERROR_INVALID_DATA;
1380 }
1381
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301382 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1383 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301384 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301385 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301386 }
1387
Andrew Jeffery66c77232024-04-24 11:42:02 +09301388 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301389 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301390 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferye5011772023-04-13 12:06:22 +09301391 }
1392
Andrew Jeffery9c766792022-08-10 23:12:49 +09301393 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301394 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301395 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301396
Andrew Jeffery66c77232024-04-24 11:42:02 +09301397 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301398 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301399 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferye5011772023-04-13 12:06:22 +09301400 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301401
1402 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301403 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301404 }
1405
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301406 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301407 if (rc) {
1408 return pldm_xlate_errno(rc);
1409 }
1410
1411 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301412}
1413
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301414LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301415int encode_event_message_buffer_size_req(uint8_t instance_id,
1416 uint16_t event_receiver_max_buffer_size,
1417 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001418{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301419 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001420 header.msg_type = PLDM_REQUEST;
1421 header.instance = instance_id;
1422 header.pldm_type = PLDM_PLATFORM;
1423 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1424
1425 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1426 if (rc != PLDM_SUCCESS) {
1427 return rc;
1428 }
1429
1430 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301431 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001432 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301433 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001434
1435 return PLDM_SUCCESS;
1436}
1437
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301438LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001439int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1440 size_t payload_length,
1441 uint8_t *completion_code,
1442 uint16_t *terminus_max_buffer_size)
1443{
Andrew Jefferya1896962025-03-03 21:41:25 +10301444 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery11126902023-04-13 12:12:10 +09301445 int rc;
1446
Dung Caod6ae8982022-11-02 10:00:10 +07001447 if (msg == NULL || completion_code == NULL ||
1448 terminus_max_buffer_size == NULL) {
1449 return PLDM_ERROR_INVALID_DATA;
1450 }
1451
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301452 rc = pldm_msgbuf_init_errno(buf,
1453 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1454 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301455 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301456 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301457 }
1458
Andrew Jeffery66c77232024-04-24 11:42:02 +09301459 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301460 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301461 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery11126902023-04-13 12:12:10 +09301462 }
1463
Dung Caod6ae8982022-11-02 10:00:10 +07001464 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301465 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Dung Caod6ae8982022-11-02 10:00:10 +07001466 }
Dung Caod6ae8982022-11-02 10:00:10 +07001467
Andrew Jeffery66c77232024-04-24 11:42:02 +09301468 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001469
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301470 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301471 if (rc) {
1472 return pldm_xlate_errno(rc);
1473 }
1474
1475 return PLDM_SUCCESS;
Dung Caod6ae8982022-11-02 10:00:10 +07001476}
1477
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301478LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001479int encode_event_message_supported_req(uint8_t instance_id,
1480 uint8_t format_version,
1481 struct pldm_msg *msg)
1482{
1483 if (format_version != 1) {
1484 return PLDM_ERROR_INVALID_DATA;
1485 }
1486
1487 if (msg == NULL) {
1488 return PLDM_ERROR_INVALID_DATA;
1489 }
1490
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301491 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001492 header.msg_type = PLDM_REQUEST;
1493 header.instance = instance_id;
1494 header.pldm_type = PLDM_PLATFORM;
1495 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1496
1497 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1498 if (rc != PLDM_SUCCESS) {
1499 return rc;
1500 }
1501
1502 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301503 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001504 request->format_version = format_version;
1505
1506 return PLDM_SUCCESS;
1507}
1508
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301509LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301510int decode_event_message_supported_resp(const struct pldm_msg *msg,
1511 size_t payload_length,
1512 uint8_t *completion_code,
1513 uint8_t *synchrony_config,
1514 bitfield8_t *synchrony_config_support,
1515 uint8_t *number_event_class_returned,
1516 uint8_t *event_class,
1517 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001518{
Andrew Jefferya1896962025-03-03 21:41:25 +10301519 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301520 int i;
1521 int rc;
1522
Dung Cao1bf8c872022-11-29 05:32:58 +07001523 if (msg == NULL || completion_code == NULL ||
1524 synchrony_config == NULL || synchrony_config_support == NULL ||
1525 number_event_class_returned == NULL || event_class == NULL) {
1526 return PLDM_ERROR_INVALID_DATA;
1527 }
1528
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301529 rc = pldm_msgbuf_init_errno(buf,
1530 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1531 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301532 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301533 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301534 }
1535
Andrew Jeffery66c77232024-04-24 11:42:02 +09301536 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301537 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301538 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301539 }
1540
Dung Cao1bf8c872022-11-29 05:32:58 +07001541 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301542 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Dung Cao1bf8c872022-11-29 05:32:58 +07001543 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301544
Andrew Jeffery66c77232024-04-24 11:42:02 +09301545 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301546 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301547 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Dung Cao1bf8c872022-11-29 05:32:58 +07001548 }
1549
Dung Cao1bf8c872022-11-29 05:32:58 +07001550 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301551 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Dung Cao1bf8c872022-11-29 05:32:58 +07001552 }
1553
Andrew Jeffery66c77232024-04-24 11:42:02 +09301554 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001555
Andrew Jeffery66c77232024-04-24 11:42:02 +09301556 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301557 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301558 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Dung Cao1bf8c872022-11-29 05:32:58 +07001559 }
1560
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301561 if (*number_event_class_returned == 0) {
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301562 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301563 if (rc) {
1564 return pldm_xlate_errno(rc);
1565 }
1566
1567 return PLDM_SUCCESS;
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301568 }
1569
1570 if (event_class_count < *number_event_class_returned) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301571 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301572 }
1573
1574 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301575 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301576 }
1577
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301578 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301579 if (rc) {
1580 return pldm_xlate_errno(rc);
1581 }
1582
1583 return PLDM_SUCCESS;
Dung Cao1bf8c872022-11-29 05:32:58 +07001584}
1585
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301586LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301587int decode_sensor_event_data(const uint8_t *event_data,
1588 size_t event_data_length, uint16_t *sensor_id,
1589 uint8_t *sensor_event_class_type,
1590 size_t *event_class_data_offset)
1591{
Andrew Jefferya1896962025-03-03 21:41:25 +10301592 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301593 int rc;
1594
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001595 if (event_data == NULL || sensor_id == NULL ||
1596 sensor_event_class_type == NULL ||
1597 event_class_data_offset == NULL) {
1598 return PLDM_ERROR_INVALID_DATA;
1599 }
1600
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301601 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1602 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301603 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301604 return pldm_xlate_errno(rc);
1605 }
1606
1607 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301608 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301609 }
1610
1611 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301612 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301613
Andrew Jeffery66c77232024-04-24 11:42:02 +09301614 pldm_msgbuf_extract_p(buf, sensor_id);
1615 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301616 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301617 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301618 }
1619
1620 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301621 if (event_class_data_length !=
1622 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301623 return pldm_msgbuf_discard(buf,
1624 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301625 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301626 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301627 if (event_class_data_length !=
1628 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301629 return pldm_msgbuf_discard(buf,
1630 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301631 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301632 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301633 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301634 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301635 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301636 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301637 return pldm_msgbuf_discard(buf,
1638 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301639 }
1640 } else {
Andrew Jefferya1896962025-03-03 21:41:25 +10301641 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301642 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301643
Andrew Jeffery9c766792022-08-10 23:12:49 +09301644 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301645 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301646
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301647 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301648 if (rc) {
1649 return pldm_xlate_errno(rc);
1650 }
1651
1652 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301653}
1654
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301655LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301656int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1657 uint8_t *present_op_state, uint8_t *previous_op_state)
1658{
Andrew Jefferya1896962025-03-03 21:41:25 +10301659 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301660 int rc;
1661
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001662 if (sensor_data == NULL || present_op_state == NULL ||
1663 previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301664 return PLDM_ERROR_INVALID_DATA;
1665 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301666
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301667 rc = pldm_msgbuf_init_errno(
1668 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1669 sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301670 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301671 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301672 }
1673
Andrew Jeffery66c77232024-04-24 11:42:02 +09301674 pldm_msgbuf_extract_p(buf, present_op_state);
1675 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301676
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301677 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301678 if (rc) {
1679 return pldm_xlate_errno(rc);
1680 }
1681
1682 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301683}
1684
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301685LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301686int decode_state_sensor_data(const uint8_t *sensor_data,
1687 size_t sensor_data_length, uint8_t *sensor_offset,
1688 uint8_t *event_state,
1689 uint8_t *previous_event_state)
1690{
Andrew Jefferya1896962025-03-03 21:41:25 +10301691 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301692 int rc;
1693
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001694 if (sensor_data == NULL || sensor_offset == NULL ||
1695 event_state == NULL || previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301696 return PLDM_ERROR_INVALID_DATA;
1697 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301698
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301699 rc = pldm_msgbuf_init_errno(
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301700 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1701 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301702 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301703 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301704 }
1705
Andrew Jeffery66c77232024-04-24 11:42:02 +09301706 pldm_msgbuf_extract_p(buf, sensor_offset);
1707 pldm_msgbuf_extract_p(buf, event_state);
1708 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301709
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301710 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301711 if (rc) {
1712 return pldm_xlate_errno(rc);
1713 }
1714
1715 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301716}
1717
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301718LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301719int decode_numeric_sensor_data(const uint8_t *sensor_data,
1720 size_t sensor_data_length, uint8_t *event_state,
1721 uint8_t *previous_event_state,
1722 uint8_t *sensor_data_size,
1723 uint32_t *present_reading)
1724{
Andrew Jefferya1896962025-03-03 21:41:25 +10301725 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301726 int rc;
1727
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001728 if (sensor_data == NULL || sensor_data_size == NULL ||
1729 event_state == NULL || previous_event_state == NULL ||
1730 present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301731 return PLDM_ERROR_INVALID_DATA;
1732 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301733
1734 if (sensor_data_length >
1735 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301736 return PLDM_ERROR_INVALID_LENGTH;
1737 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301738
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301739 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301740 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1741 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301742 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301743 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301744 }
1745
Andrew Jeffery66c77232024-04-24 11:42:02 +09301746 pldm_msgbuf_extract_p(buf, event_state);
1747 pldm_msgbuf_extract_p(buf, previous_event_state);
1748 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301749 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301750 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery155317e2023-04-13 18:36:51 +09301751 }
1752
1753 /*
1754 * The implementation below is bonkers, but it's because the function
1755 * prototype is bonkers. The `present_reading` argument should have been
1756 * a tagged union.
1757 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301758 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301759 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1760 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301761 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301762 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301763 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301764 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301765 }
1766 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1767 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301768 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301769 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301770 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301771 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301772 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301773 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301774 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301775 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301776 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301777 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301778 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301779 }
1780 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301781 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301782 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301783 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301784 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301785 break;
1786 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301787 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1788 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301789 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301790 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301791 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301792 break;
1793 }
1794 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1795 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301796 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301797 *present_reading = (uint32_t)val;
1798 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301799 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301800 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301801 default:
Andrew Jefferya1896962025-03-03 21:41:25 +10301802 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301803 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301804
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301805 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301806 if (rc) {
1807 return pldm_xlate_errno(rc);
1808 }
1809
1810 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301811}
1812
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301813LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301814int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301815 const void *pdr_data, size_t pdr_data_length,
1816 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301817{
Andrew Jefferya1896962025-03-03 21:41:25 +10301818 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301819 int rc;
1820
Andrew Jefferya1896962025-03-03 21:41:25 +10301821 if (!pdr_data || !pdr_value) {
1822 return PLDM_ERROR_INVALID_DATA;
1823 }
1824
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301825 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1826 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301827 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301828 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301829 }
1830
Andrew Jeffery329176a2024-09-26 22:38:24 +09301831 rc = pldm_msgbuf_extract_value_pdr_hdr(
1832 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301833 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301834 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301835 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301836 }
1837
Andrew Jeffery66c77232024-04-24 11:42:02 +09301838 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1839 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1840 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1841 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1842 pldm_msgbuf_extract(buf, pdr_value->container_id);
1843 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1844 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1845 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1846 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1847 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1848 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1849 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1850 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1851 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1852 pldm_msgbuf_extract(buf, pdr_value->rel);
1853 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1854 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301855
Andrew Jeffery66c77232024-04-24 11:42:02 +09301856 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301857 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301858 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301859 }
1860 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301861 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301862 }
1863
Andrew Jeffery66c77232024-04-24 11:42:02 +09301864 pldm_msgbuf_extract(buf, pdr_value->resolution);
1865 pldm_msgbuf_extract(buf, pdr_value->offset);
1866 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1867 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1868 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301869 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1870 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301871 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301872 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301873 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1874 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1875 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301876 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1877 &pdr_value->max_readable);
1878 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1879 &pdr_value->min_readable);
1880
Andrew Jeffery66c77232024-04-24 11:42:02 +09301881 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301882 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301883 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301884 }
1885 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301886 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301887 }
1888
Andrew Jeffery66c77232024-04-24 11:42:02 +09301889 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301890 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301891 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301892 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301893 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301894 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301895 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301896 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301897 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301898 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301899 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301900 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301901 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301902 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301903 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301904 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301905 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301906 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301907 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301908
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301909 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301910 if (rc) {
1911 return pldm_xlate_errno(rc);
1912 }
1913
1914 return PLDM_SUCCESS;
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301915}
1916
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301917LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301918int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1919 uint16_t effecter_id,
1920 struct pldm_msg *msg)
1921{
1922 if (msg == NULL) {
1923 return PLDM_ERROR_INVALID_DATA;
1924 }
1925
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301926 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301927 header.msg_type = PLDM_REQUEST;
1928 header.instance = instance_id;
1929 header.pldm_type = PLDM_PLATFORM;
1930 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1931
1932 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1933 if (rc != PLDM_SUCCESS) {
1934 return rc;
1935 }
1936
1937 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301938 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301939 request->effecter_id = htole16(effecter_id);
1940
1941 return PLDM_SUCCESS;
1942}
1943
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301944LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301945int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301946 uint8_t instance_id, uint8_t completion_code,
1947 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1948 const uint8_t *pending_value, const uint8_t *present_value,
1949 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301950{
1951 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1952 return PLDM_ERROR_INVALID_DATA;
1953 }
1954
1955 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1956 return PLDM_ERROR_INVALID_DATA;
1957 }
1958
1959 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1960 return PLDM_ERROR_INVALID_DATA;
1961 }
1962
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301963 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301964 header.msg_type = PLDM_RESPONSE;
1965 header.instance = instance_id;
1966 header.pldm_type = PLDM_PLATFORM;
1967 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1968
1969 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1970 if (rc != PLDM_SUCCESS) {
1971 return rc;
1972 }
1973
1974 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301975 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301976
1977 response->completion_code = completion_code;
1978 response->effecter_data_size = effecter_data_size;
1979 response->effecter_oper_state = effecter_oper_state;
1980
1981 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1982 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1983 if (payload_length !=
1984 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1985 return PLDM_ERROR_INVALID_LENGTH;
1986 }
1987 response->pending_and_present_values[0] = *pending_value;
1988 response->pending_and_present_values[1] = *present_value;
1989
1990 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1991 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1992 if (payload_length !=
1993 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1994 return PLDM_ERROR_INVALID_LENGTH;
1995 }
1996 uint16_t val_pending = *(uint16_t *)pending_value;
1997 val_pending = htole16(val_pending);
1998 memcpy(response->pending_and_present_values, &val_pending,
1999 sizeof(uint16_t));
2000 uint16_t val_present = *(uint16_t *)present_value;
2001 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302002 memcpy((response->pending_and_present_values +
2003 sizeof(uint16_t)),
2004 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302005
2006 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2007 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2008 if (payload_length !=
2009 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
2010 return PLDM_ERROR_INVALID_LENGTH;
2011 }
2012 uint32_t val_pending = *(uint32_t *)pending_value;
2013 val_pending = htole32(val_pending);
2014 memcpy(response->pending_and_present_values, &val_pending,
2015 sizeof(uint32_t));
2016 uint32_t val_present = *(uint32_t *)present_value;
2017 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302018 memcpy((response->pending_and_present_values +
2019 sizeof(uint32_t)),
2020 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302021 }
2022 return PLDM_SUCCESS;
2023}
2024
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302025LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302026int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
2027 size_t payload_length,
2028 uint16_t *effecter_id)
2029{
Andrew Jefferya1896962025-03-03 21:41:25 +10302030 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydd265822023-04-13 22:42:44 +09302031 int rc;
2032
Andrew Jeffery9c766792022-08-10 23:12:49 +09302033 if (msg == NULL || effecter_id == NULL) {
2034 return PLDM_ERROR_INVALID_DATA;
2035 }
2036
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302037 rc = pldm_msgbuf_init_errno(buf,
2038 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2039 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09302040 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302041 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302042 }
2043
Andrew Jeffery66c77232024-04-24 11:42:02 +09302044 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302045
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302046 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302047 if (rc) {
2048 return pldm_xlate_errno(rc);
2049 }
2050
2051 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302052}
2053
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302054LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302055int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2056 size_t payload_length,
2057 uint8_t *completion_code,
2058 uint8_t *effecter_data_size,
2059 uint8_t *effecter_oper_state,
2060 uint8_t *pending_value,
2061 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302062{
Andrew Jefferya1896962025-03-03 21:41:25 +10302063 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302064 int rc;
2065
Andrew Jeffery9c766792022-08-10 23:12:49 +09302066 if (msg == NULL || effecter_data_size == NULL ||
2067 effecter_oper_state == NULL || pending_value == NULL ||
2068 present_value == NULL) {
2069 return PLDM_ERROR_INVALID_DATA;
2070 }
2071
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302072 rc = pldm_msgbuf_init_errno(
2073 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2074 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302075 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302076 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302077 }
2078
Andrew Jeffery66c77232024-04-24 11:42:02 +09302079 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302080 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302081 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302082 }
2083
Andrew Jeffery9c766792022-08-10 23:12:49 +09302084 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302085 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302086 }
2087
Andrew Jeffery66c77232024-04-24 11:42:02 +09302088 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302089 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302090 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302091 }
2092
Andrew Jeffery9c766792022-08-10 23:12:49 +09302093 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302094 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302095 }
2096
Andrew Jeffery66c77232024-04-24 11:42:02 +09302097 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302098 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302099 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302100 }
2101
Andrew Jeffery9c766792022-08-10 23:12:49 +09302102 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302103 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302104 }
2105
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302106 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2107 pending_value);
2108 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2109 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302110
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302111 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302112 if (rc) {
2113 return pldm_xlate_errno(rc);
2114 }
2115
2116 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302117}
2118
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302119LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302120int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302121 uint8_t event_data_format, uint8_t number_of_change_records,
2122 const uint8_t *event_data_operations,
2123 const uint8_t *numbers_of_change_entries,
2124 const uint32_t *const *change_entries,
2125 struct pldm_pdr_repository_chg_event_data *event_data,
2126 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302127{
2128 if (event_data_operations == NULL ||
2129 numbers_of_change_entries == NULL || change_entries == NULL) {
2130 return PLDM_ERROR_INVALID_DATA;
2131 }
2132
2133 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302134 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302135
2136 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302137 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302138 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302139 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302140
2141 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302142 expected_size += sizeof(*change_entries[0]) *
2143 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302144 }
2145
2146 *actual_change_records_size = expected_size;
2147
2148 if (event_data == NULL) {
2149 return PLDM_SUCCESS;
2150 }
2151
2152 if (max_change_records_size < expected_size) {
2153 return PLDM_ERROR_INVALID_LENGTH;
2154 }
2155
2156 event_data->event_data_format = event_data_format;
2157 event_data->number_of_change_records = number_of_change_records;
2158
2159 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302160 (struct pldm_pdr_repository_change_record_data *)
2161 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302162
2163 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2164 record_data->event_data_operation = event_data_operations[i];
2165 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302166 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302167
2168 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2169 ++j) {
2170 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302171 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302172 }
2173
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302174 record_data =
2175 (struct pldm_pdr_repository_change_record_data
2176 *)(record_data->change_entry +
2177 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302178 }
2179
2180 return PLDM_SUCCESS;
2181}
2182
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302183LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302184int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2185 size_t event_data_size,
2186 uint8_t *event_data_format,
2187 uint8_t *number_of_change_records,
2188 size_t *change_record_data_offset)
2189{
Andrew Jefferya1896962025-03-03 21:41:25 +10302190 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302191 int rc;
2192
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002193 if (event_data == NULL || event_data_format == NULL ||
2194 number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302195 change_record_data_offset == NULL) {
2196 return PLDM_ERROR_INVALID_DATA;
2197 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302198
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302199 rc = pldm_msgbuf_init_errno(buf,
2200 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2201 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302202 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302203 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302204 }
2205
Andrew Jeffery66c77232024-04-24 11:42:02 +09302206 pldm_msgbuf_extract_p(buf, event_data_format);
2207 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302208
Andrew Jeffery9c766792022-08-10 23:12:49 +09302209 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302210 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302211
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302212 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302213 if (rc) {
2214 return pldm_xlate_errno(rc);
2215 }
2216
2217 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302218}
2219
Thu Nguyenf874b382024-07-24 11:22:34 +00002220LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00002221int decode_pldm_message_poll_event_data(
2222 const void *event_data, size_t event_data_length,
2223 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07002224{
Andrew Jefferya1896962025-03-03 21:41:25 +10302225 PLDM_MSGBUF_DEFINE_P(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002226 int rc;
2227
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002228 if (!event_data || !poll_event) {
Thu Nguyen7739d122024-07-26 11:36:39 +00002229 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07002230 }
2231
Thu Nguyen7739d122024-07-26 11:36:39 +00002232 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2233 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002234 if (rc) {
2235 return rc;
2236 }
2237
Thu Nguyen7739d122024-07-26 11:36:39 +00002238 pldm_msgbuf_extract(buf, poll_event->format_version);
2239 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07002240 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302241 return pldm_msgbuf_discard(buf, rc);
Dung Cao7c250342022-11-16 22:40:37 +07002242 }
2243
Thu Nguyen7739d122024-07-26 11:36:39 +00002244 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302245 return pldm_msgbuf_discard(buf, -EPROTO);
Dung Cao7c250342022-11-16 22:40:37 +07002246 }
2247
Thu Nguyen7739d122024-07-26 11:36:39 +00002248 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002249
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302250 return pldm_msgbuf_complete_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002251}
2252
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302253LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00002254int encode_pldm_message_poll_event_data(
2255 const struct pldm_message_poll_event *poll_event, void *event_data,
2256 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07002257{
Andrew Jefferya1896962025-03-03 21:41:25 +10302258 PLDM_MSGBUF_DEFINE_P(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002259 int rc;
2260
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002261 if (poll_event == NULL || event_data == NULL) {
2262 return -EINVAL;
2263 }
2264
Thu Nguyen7739d122024-07-26 11:36:39 +00002265 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2266 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002267 }
2268
Thu Nguyen7739d122024-07-26 11:36:39 +00002269 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2270 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002271 if (rc) {
2272 return rc;
2273 }
Thu Nguyen7739d122024-07-26 11:36:39 +00002274 pldm_msgbuf_insert(buf, poll_event->format_version);
2275 pldm_msgbuf_insert(buf, poll_event->event_id);
2276 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002277
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302278 return pldm_msgbuf_complete_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002279}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302280
2281LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302282int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302283 const uint8_t *change_record_data, size_t change_record_data_size,
2284 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
2285 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302286{
Andrew Jefferya1896962025-03-03 21:41:25 +10302287 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302288 int rc;
2289
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002290 if (change_record_data == NULL || event_data_operation == NULL ||
2291 number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302292 change_entry_data_offset == NULL) {
2293 return PLDM_ERROR_INVALID_DATA;
2294 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302295
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302296 rc = pldm_msgbuf_init_errno(
2297 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2298 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302299 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302300 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302301 }
2302
Andrew Jeffery66c77232024-04-24 11:42:02 +09302303 pldm_msgbuf_extract_p(buf, event_data_operation);
2304 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302305
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302306 *change_entry_data_offset = sizeof(*event_data_operation) +
2307 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302308
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302309 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302310 if (rc) {
2311 return pldm_xlate_errno(rc);
2312 }
2313
2314 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302315}
2316
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302317LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302318int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2319 uint8_t rearm_event_state,
2320 struct pldm_msg *msg)
2321{
2322 if (msg == NULL) {
2323 return PLDM_ERROR_INVALID_DATA;
2324 }
2325
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302326 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302327 header.msg_type = PLDM_REQUEST;
2328 header.instance = instance_id;
2329 header.pldm_type = PLDM_PLATFORM;
2330 header.command = PLDM_GET_SENSOR_READING;
2331
2332 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2333 if (rc != PLDM_SUCCESS) {
2334 return rc;
2335 }
2336
2337 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302338 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302339
2340 request->sensor_id = htole16(sensor_id);
2341 request->rearm_event_state = rearm_event_state;
2342
2343 return PLDM_SUCCESS;
2344}
2345
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302346LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302347int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302348 const struct pldm_msg *msg, size_t payload_length,
2349 uint8_t *completion_code, uint8_t *sensor_data_size,
2350 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2351 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2352 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302353{
Andrew Jefferya1896962025-03-03 21:41:25 +10302354 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302355 int rc;
2356
Andrew Jeffery9c766792022-08-10 23:12:49 +09302357 if (msg == NULL || completion_code == NULL ||
2358 sensor_data_size == NULL || sensor_operational_state == NULL ||
2359 sensor_event_message_enable == NULL || present_state == NULL ||
2360 previous_state == NULL || event_state == NULL ||
2361 present_reading == NULL) {
2362 return PLDM_ERROR_INVALID_DATA;
2363 }
2364
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302365 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2366 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302367 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302368 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302369 }
2370
Andrew Jeffery66c77232024-04-24 11:42:02 +09302371 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302372 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302373 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery840b1402023-04-13 23:54:44 +09302374 }
2375
Andrew Jeffery9c766792022-08-10 23:12:49 +09302376 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302377 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302378 }
2379
Andrew Jeffery66c77232024-04-24 11:42:02 +09302380 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302381 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302382 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302383 }
2384
Andrew Jeffery840b1402023-04-13 23:54:44 +09302385 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302386 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302387 }
2388
Andrew Jeffery66c77232024-04-24 11:42:02 +09302389 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2390 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2391 pldm_msgbuf_extract_p(buf, present_state);
2392 pldm_msgbuf_extract_p(buf, previous_state);
2393 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302394
Andrew Jeffery840b1402023-04-13 23:54:44 +09302395 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2396 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302397
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302398 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302399 if (rc) {
2400 return pldm_xlate_errno(rc);
2401 }
2402
2403 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302404}
2405
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302406LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302407int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2408 uint8_t sensor_data_size,
2409 uint8_t sensor_operational_state,
2410 uint8_t sensor_event_message_enable,
2411 uint8_t present_state,
2412 uint8_t previous_state, uint8_t event_state,
2413 const uint8_t *present_reading,
2414 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302415{
2416 if (msg == NULL || present_reading == NULL) {
2417 return PLDM_ERROR_INVALID_DATA;
2418 }
2419
2420 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2421 return PLDM_ERROR_INVALID_DATA;
2422 }
2423
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302424 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302425 header.msg_type = PLDM_RESPONSE;
2426 header.instance = instance_id;
2427 header.pldm_type = PLDM_PLATFORM;
2428 header.command = PLDM_GET_SENSOR_READING;
2429
2430 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2431 if (rc != PLDM_SUCCESS) {
2432 return rc;
2433 }
2434
2435 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302436 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302437
2438 response->completion_code = completion_code;
2439 response->sensor_data_size = sensor_data_size;
2440 response->sensor_operational_state = sensor_operational_state;
2441 response->sensor_event_message_enable = sensor_event_message_enable;
2442 response->present_state = present_state;
2443 response->previous_state = previous_state;
2444 response->event_state = event_state;
2445
2446 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2447 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2448 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2449 return PLDM_ERROR_INVALID_LENGTH;
2450 }
2451 response->present_reading[0] = *present_reading;
2452
2453 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2454 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2455 if (payload_length !=
2456 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2457 return PLDM_ERROR_INVALID_LENGTH;
2458 }
2459 uint16_t val = *(uint16_t *)present_reading;
2460 val = htole16(val);
2461 memcpy(response->present_reading, &val, 2);
2462
2463 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2464 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2465 if (payload_length !=
2466 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2467 return PLDM_ERROR_INVALID_LENGTH;
2468 }
2469 uint32_t val = *(uint32_t *)present_reading;
2470 val = htole32(val);
2471 memcpy(response->present_reading, &val, 4);
2472 }
2473
2474 return PLDM_SUCCESS;
2475}
2476
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302477LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302478int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2479 size_t payload_length, uint16_t *sensor_id,
2480 uint8_t *rearm_event_state)
2481{
Andrew Jefferya1896962025-03-03 21:41:25 +10302482 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302483 int rc;
2484
Andrew Jeffery9c766792022-08-10 23:12:49 +09302485 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2486 return PLDM_ERROR_INVALID_DATA;
2487 }
2488
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302489 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2490 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302491 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302492 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302493 }
2494
Andrew Jeffery66c77232024-04-24 11:42:02 +09302495 pldm_msgbuf_extract_p(buf, sensor_id);
2496 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302497
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302498 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302499 if (rc) {
2500 return pldm_xlate_errno(rc);
2501 }
2502
2503 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302504}
2505
Roger G. Coscojuelababd7b12025-03-14 10:11:18 +01002506LIBPLDM_ABI_TESTING
Matt Johnstonea5f7372025-06-20 17:49:54 +08002507int decode_set_numeric_sensor_enable_req(
2508 const struct pldm_msg *msg, size_t payload_length,
2509 struct pldm_set_numeric_sensor_enable_req *req)
2510{
2511 PLDM_MSGBUF_DEFINE_P(buf);
2512 uint8_t event_enable = 0;
2513 uint8_t op_state = 0;
2514 int rc;
2515
2516 if (msg == NULL || req == NULL) {
2517 return -EINVAL;
2518 }
2519
2520 rc = pldm_msgbuf_init_errno(buf, 0, msg->payload, payload_length);
2521 if (rc) {
2522 return rc;
2523 }
2524
2525 pldm_msgbuf_extract(buf, req->sensor_id);
2526 pldm_msgbuf_extract(buf, op_state);
2527 pldm_msgbuf_extract(buf, event_enable);
2528
2529 rc = pldm_msgbuf_complete_consumed(buf);
2530 if (rc) {
2531 return rc;
2532 }
2533
2534 if (op_state > PLDM_SET_SENSOR_UNAVAILABLE) {
2535 return -EPROTO;
2536 }
2537
2538 if (event_enable > PLDM_STATE_EVENTS_ONLY_ENABLED) {
2539 return -EPROTO;
2540 }
2541
2542 req->op_state = op_state;
2543 req->event_enable = event_enable;
2544
2545 return 0;
2546}
2547
2548LIBPLDM_ABI_TESTING
2549int decode_set_state_sensor_enables_req(
2550 const struct pldm_msg *msg, size_t payload_length,
2551 struct pldm_set_state_sensor_enables_req *req)
2552{
2553 PLDM_MSGBUF_DEFINE_P(buf);
2554 int rc;
2555
2556 if (msg == NULL || req == NULL) {
2557 return -EINVAL;
2558 }
2559
2560 rc = pldm_msgbuf_init_errno(buf, 3, msg->payload, payload_length);
2561 if (rc) {
2562 return rc;
2563 }
2564
2565 pldm_msgbuf_extract(buf, req->sensor_id);
2566 rc = pldm_msgbuf_extract(buf, req->field_count);
2567 if (rc) {
2568 return rc;
2569 }
2570
2571 if (req->field_count < 1 ||
2572 req->field_count > PLDM_SET_STATE_SENSOR_ENABLES_MAX_COUNT) {
2573 return -EPROTO;
2574 }
2575
2576 for (uint8_t i = 0; i < req->field_count; i++) {
2577 uint8_t event_enable_val = 0;
2578 uint8_t op_state_val = 0;
2579
2580 pldm_msgbuf_extract(buf, op_state_val);
2581 rc = pldm_msgbuf_extract(buf, event_enable_val);
2582 if (rc) {
2583 return pldm_msgbuf_discard(buf, rc);
2584 }
2585
2586 if (op_state_val > PLDM_SET_SENSOR_UNAVAILABLE) {
2587 return pldm_msgbuf_discard(buf, -EPROTO);
2588 }
2589
2590 if (event_enable_val > PLDM_STATE_EVENTS_ONLY_ENABLED) {
2591 return pldm_msgbuf_discard(buf, -EPROTO);
2592 }
2593
2594 req->fields[i].op_state = op_state_val;
2595 req->fields[i].event_enable = event_enable_val;
2596 }
2597
2598 return pldm_msgbuf_complete_consumed(buf);
2599}
2600
2601LIBPLDM_ABI_TESTING
Roger G. Coscojuelababd7b12025-03-14 10:11:18 +01002602int encode_get_event_receiver_req(uint8_t instance_id, struct pldm_msg *msg,
2603 size_t payload_length LIBPLDM_CC_UNUSED)
2604{
2605 struct pldm_header_info header;
2606 header.msg_type = PLDM_REQUEST;
2607 header.instance = instance_id;
2608 header.pldm_type = PLDM_PLATFORM;
2609 header.command = PLDM_GET_EVENT_RECEIVER;
2610
2611 if (!msg) {
2612 return -EINVAL;
2613 }
2614
2615 return pack_pldm_header_errno(&header, &(msg->hdr));
2616}
2617
2618LIBPLDM_ABI_TESTING
2619int encode_get_event_receiver_resp(
2620 uint8_t instance_id,
2621 struct pldm_get_event_receiver_resp *event_receiver_info,
2622 struct pldm_msg *msg, size_t *payload_length)
2623{
2624 PLDM_MSGBUF_DEFINE_P(buf);
2625 int rc;
2626 if (!msg || !event_receiver_info) {
2627 return -EINVAL;
2628 }
2629
2630 /* See Table 2, DSP0245 v1.4.0 */
2631 if (event_receiver_info->transport_protocol_type !=
2632 PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2633 return -ENOTSUP;
2634 }
2635
2636 struct pldm_header_info header = { 0 };
2637 header.msg_type = PLDM_RESPONSE;
2638 header.instance = instance_id;
2639 header.pldm_type = PLDM_PLATFORM;
2640 header.command = PLDM_GET_EVENT_RECEIVER;
2641
2642 rc = pack_pldm_header_errno(&header, &(msg->hdr));
2643 if (rc) {
2644 return rc;
2645 }
2646 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES,
2647 msg->payload, *payload_length);
2648 if (rc) {
2649 return rc;
2650 }
2651
2652 pldm_msgbuf_insert(buf, event_receiver_info->completion_code);
2653 pldm_msgbuf_insert(buf, event_receiver_info->transport_protocol_type);
2654 pldm_msgbuf_insert(
2655 buf, event_receiver_info->event_receiver_address.mctp_eid);
2656 return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
2657}
2658
Roger G. Coscojuela684a9ab2025-06-12 14:56:44 +02002659LIBPLDM_ABI_STABLE
Roger G. Coscojuelababd7b12025-03-14 10:11:18 +01002660int decode_get_event_receiver_resp(const struct pldm_msg *msg,
2661 size_t payload_length,
2662 struct pldm_get_event_receiver_resp *resp)
2663{
2664 PLDM_MSGBUF_DEFINE_P(buf);
2665 int rc;
2666 if (!msg) {
2667 return -EINVAL;
2668 }
2669
2670 rc = pldm_msg_has_error(msg, payload_length);
2671 if (rc) {
2672 resp->completion_code = rc;
2673 return 0;
2674 }
2675
2676 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES,
2677 msg->payload, payload_length);
2678 if (rc) {
2679 return rc;
2680 }
2681 pldm_msgbuf_extract(buf, resp->completion_code);
2682 rc = pldm_msgbuf_extract(buf, resp->transport_protocol_type);
2683 if (rc) {
2684 return pldm_msgbuf_discard(buf, rc);
2685 }
2686 if (resp->transport_protocol_type ==
2687 PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2688 pldm_msgbuf_extract(buf, resp->event_receiver_address.mctp_eid);
2689 } else {
2690 return pldm_msgbuf_discard(buf, -ENOTSUP);
2691 }
2692 return pldm_msgbuf_complete_consumed(buf);
2693}
2694
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302695LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302696int encode_set_event_receiver_req(uint8_t instance_id,
2697 uint8_t event_message_global_enable,
2698 uint8_t transport_protocol_type,
2699 uint8_t event_receiver_address_info,
2700 uint16_t heartbeat_timer,
2701 struct pldm_msg *msg)
2702{
2703 if (msg == NULL) {
2704 return PLDM_ERROR_INVALID_DATA;
2705 }
2706
2707 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2708 return PLDM_ERROR_INVALID_DATA;
2709 }
2710
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302711 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302712 header.msg_type = PLDM_REQUEST;
2713 header.instance = instance_id;
2714 header.pldm_type = PLDM_PLATFORM;
2715 header.command = PLDM_SET_EVENT_RECEIVER;
2716
2717 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2718 if (rc != PLDM_SUCCESS) {
2719 return rc;
2720 }
2721
2722 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302723 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302724 request->event_message_global_enable = event_message_global_enable;
2725
2726 request->transport_protocol_type = transport_protocol_type;
2727 request->event_receiver_address_info = event_receiver_address_info;
2728
2729 if (event_message_global_enable ==
2730 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2731 if (heartbeat_timer == 0) {
2732 return PLDM_ERROR_INVALID_DATA;
2733 }
2734 request->heartbeat_timer = htole16(heartbeat_timer);
2735 }
2736
2737 return PLDM_SUCCESS;
2738}
2739
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302740LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302741int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2742 size_t payload_length,
2743 uint8_t *completion_code)
2744{
Andrew Jefferya1896962025-03-03 21:41:25 +10302745 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302746 int rc;
2747
Andrew Jeffery9c766792022-08-10 23:12:49 +09302748 if (msg == NULL || completion_code == NULL) {
2749 return PLDM_ERROR_INVALID_DATA;
2750 }
2751
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302752 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2753 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302754 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302755 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302756 }
2757
Andrew Jeffery66c77232024-04-24 11:42:02 +09302758 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302759
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302760 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302761 if (rc) {
2762 return pldm_xlate_errno(rc);
2763 }
2764
2765 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302766}
2767
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302768LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302769int decode_set_event_receiver_req(const struct pldm_msg *msg,
2770 size_t payload_length,
2771 uint8_t *event_message_global_enable,
2772 uint8_t *transport_protocol_type,
2773 uint8_t *event_receiver_address_info,
2774 uint16_t *heartbeat_timer)
2775
2776{
Andrew Jefferya1896962025-03-03 21:41:25 +10302777 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302778 int rc;
2779
Andrew Jeffery9c766792022-08-10 23:12:49 +09302780 if (msg == NULL || event_message_global_enable == NULL ||
2781 transport_protocol_type == NULL ||
2782 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2783 return PLDM_ERROR_INVALID_DATA;
2784 }
2785
Gilbert Chen98e137d2024-10-08 08:00:39 +00002786 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_MIN_REQ_BYTES,
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302787 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302788 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302789 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302790 }
2791
Andrew Jeffery66c77232024-04-24 11:42:02 +09302792 pldm_msgbuf_extract_p(buf, event_message_global_enable);
Gilbert Chen98e137d2024-10-08 08:00:39 +00002793 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302794 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Gilbert Chen98e137d2024-10-08 08:00:39 +00002795 }
2796
Andrew Jeffery66c77232024-04-24 11:42:02 +09302797 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2798 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
Matt Johnston56ef86a2024-11-12 16:27:19 +08002799 if (*event_message_global_enable ==
2800 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
Gilbert Chen98e137d2024-10-08 08:00:39 +00002801 pldm_msgbuf_extract_p(buf, heartbeat_timer);
2802 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09302803
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302804 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302805 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302806 return pldm_xlate_errno(rc);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302807 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302808
Andrew Jeffery9c766792022-08-10 23:12:49 +09302809 if ((*event_message_global_enable ==
2810 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2811 (*heartbeat_timer == 0)) {
2812 return PLDM_ERROR_INVALID_DATA;
2813 }
2814
Andrew Jeffery9c766792022-08-10 23:12:49 +09302815 return PLDM_SUCCESS;
2816}
2817
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302818LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302819int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2820 struct pldm_msg *msg)
2821
2822{
2823 if (msg == NULL) {
2824 return PLDM_ERROR_INVALID_DATA;
2825 }
2826
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302827 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302828 header.instance = instance_id;
2829 header.msg_type = PLDM_RESPONSE;
2830 header.pldm_type = PLDM_PLATFORM;
2831 header.command = PLDM_SET_EVENT_RECEIVER;
2832
2833 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2834 if (rc != PLDM_SUCCESS) {
2835 return rc;
2836 }
2837
2838 msg->payload[0] = completion_code;
2839
2840 return PLDM_SUCCESS;
2841}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002842
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302843LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002844int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2845 uint8_t format_version,
2846 uint8_t transfer_operation_flag,
2847 uint32_t data_transfer_handle,
2848 uint16_t event_id_to_acknowledge,
2849 struct pldm_msg *msg,
2850 size_t payload_length)
2851{
Andrew Jefferya1896962025-03-03 21:41:25 +10302852 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002853 int rc;
2854
2855 if (msg == NULL) {
2856 return PLDM_ERROR_INVALID_DATA;
2857 }
2858
Thu Nguyen387b10f2024-09-24 11:33:16 +00002859 rc = pldm_platform_poll_for_platform_event_message_validate(
2860 transfer_operation_flag, event_id_to_acknowledge);
2861 if (rc < 0) {
2862 return PLDM_ERROR_INVALID_DATA;
2863 }
2864
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302865 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002866 header.msg_type = PLDM_REQUEST;
2867 header.instance = instance_id;
2868 header.pldm_type = PLDM_PLATFORM;
2869 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2870
2871 rc = pack_pldm_header(&header, &(msg->hdr));
2872 if (rc != PLDM_SUCCESS) {
2873 return rc;
2874 }
2875
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302876 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302877 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2878 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002879 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302880 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002881 }
2882
2883 pldm_msgbuf_insert(buf, format_version);
2884 pldm_msgbuf_insert(buf, transfer_operation_flag);
2885 pldm_msgbuf_insert(buf, data_transfer_handle);
2886 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2887
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302888 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302889 if (rc) {
2890 return pldm_xlate_errno(rc);
2891 }
2892
2893 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002894}
2895
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302896LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002897int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302898 const struct pldm_msg *msg, size_t payload_length,
2899 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2900 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2901 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2902 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002903{
Andrew Jefferya1896962025-03-03 21:41:25 +10302904 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002905 int rc;
2906
2907 if (msg == NULL || completion_code == NULL || tid == NULL ||
2908 event_id == NULL || next_data_transfer_handle == NULL ||
2909 transfer_flag == NULL || event_class == NULL ||
2910 event_data_size == NULL || event_data == NULL ||
2911 event_data_integrity_checksum == NULL) {
2912 return PLDM_ERROR_INVALID_DATA;
2913 }
2914
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302915 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302916 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2917 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002918 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302919 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002920 }
2921
Andrew Jeffery66c77232024-04-24 11:42:02 +09302922 rc = pldm_msgbuf_extract_p(buf, completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002923 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302924 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002925 }
2926 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302927 return pldm_msgbuf_discard(buf, *completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002928 }
2929
Andrew Jeffery66c77232024-04-24 11:42:02 +09302930 pldm_msgbuf_extract_p(buf, tid);
2931 rc = pldm_msgbuf_extract_p(buf, event_id);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002932 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302933 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002934 }
2935 if ((*event_id == 0) || (*event_id == 0xffff)) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302936 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002937 }
2938
Andrew Jeffery66c77232024-04-24 11:42:02 +09302939 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2940 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002941 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302942 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002943 }
2944
Andrew Jeffery66c77232024-04-24 11:42:02 +09302945 pldm_msgbuf_extract_p(buf, event_class);
2946 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002947 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302948 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002949 }
2950 if (*event_data_size > payload_length) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302951 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002952 }
2953
2954 if (*event_data_size > 0) {
2955 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2956 }
2957
2958 if (*transfer_flag == PLDM_END ||
2959 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302960 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002961 }
2962
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302963 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302964 if (rc) {
2965 return pldm_xlate_errno(rc);
2966 }
2967
2968 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002969}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002970
2971LIBPLDM_ABI_TESTING
2972int decode_numeric_effecter_pdr_data(
2973 const void *pdr_data, size_t pdr_data_length,
2974 struct pldm_numeric_effecter_value_pdr *pdr_value)
2975{
Andrew Jefferya1896962025-03-03 21:41:25 +10302976 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002977 struct pldm_value_pdr_hdr hdr;
2978 int rc;
2979
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002980 if (!pdr_data || !pdr_value) {
2981 return PLDM_ERROR_INVALID_DATA;
2982 }
2983
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302984 rc = pldm_msgbuf_init_errno(buf,
2985 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2986 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002987 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302988 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002989 }
2990
Andrew Jeffery329176a2024-09-26 22:38:24 +09302991 rc = pldm_msgbuf_extract_value_pdr_hdr(
2992 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
Thu Nguyend4878cd2023-11-09 10:18:33 +07002993 pdr_data_length);
2994 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09302995 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002996 }
2997
2998 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2999
3000 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
3001 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
3002 pldm_msgbuf_extract(buf, pdr_value->entity_type);
3003 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
3004 pldm_msgbuf_extract(buf, pdr_value->container_id);
3005 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
3006 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
3007 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
3008 pldm_msgbuf_extract(buf, pdr_value->base_unit);
3009 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
3010 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
3011 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
3012 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
3013 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
3014 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
3015 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
3016 pldm_msgbuf_extract(buf, pdr_value->is_linear);
3017
3018 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
3019 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303020 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyend4878cd2023-11-09 10:18:33 +07003021 }
3022 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303023 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyend4878cd2023-11-09 10:18:33 +07003024 }
3025
3026 pldm_msgbuf_extract(buf, pdr_value->resolution);
3027 pldm_msgbuf_extract(buf, pdr_value->offset);
3028 pldm_msgbuf_extract(buf, pdr_value->accuracy);
3029 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
3030 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
3031 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
3032 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
3033 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
3034 pdr_value->max_settable);
3035 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
3036 pdr_value->min_settable);
3037
3038 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
3039 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303040 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyend4878cd2023-11-09 10:18:33 +07003041 }
3042 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303043 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyend4878cd2023-11-09 10:18:33 +07003044 }
3045
3046 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
3047 pldm_msgbuf_extract_range_field_format(
3048 buf, pdr_value->range_field_format, pdr_value->nominal_value);
3049 pldm_msgbuf_extract_range_field_format(
3050 buf, pdr_value->range_field_format, pdr_value->normal_max);
3051 pldm_msgbuf_extract_range_field_format(
3052 buf, pdr_value->range_field_format, pdr_value->normal_min);
3053 pldm_msgbuf_extract_range_field_format(
3054 buf, pdr_value->range_field_format, pdr_value->rated_max);
3055 pldm_msgbuf_extract_range_field_format(
3056 buf, pdr_value->range_field_format, pdr_value->rated_min);
3057
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303058 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09303059 if (rc) {
3060 return pldm_xlate_errno(rc);
3061 }
3062
3063 return PLDM_SUCCESS;
Thu Nguyend4878cd2023-11-09 10:18:33 +07003064}
Tal Yacobia6fa5552024-05-05 16:57:38 +03003065
Tal Yacobide67ab62024-05-30 22:36:50 +03003066LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03003067int encode_get_state_effecter_states_req(uint8_t instance_id,
3068 uint16_t effecter_id,
3069 struct pldm_msg *msg,
3070 size_t payload_length)
3071{
Andrew Jefferya1896962025-03-03 21:41:25 +10303072 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003073 int rc;
3074
3075 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03003076 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03003077 }
3078
3079 struct pldm_header_info header = { 0 };
3080 header.msg_type = PLDM_REQUEST;
3081 header.instance = instance_id;
3082 header.pldm_type = PLDM_PLATFORM;
3083 header.command = PLDM_GET_STATE_EFFECTER_STATES;
3084
Tal Yacobif490a382024-05-31 09:57:36 +03003085 rc = pack_pldm_header_errno(&header, &msg->hdr);
3086 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03003087 return rc;
3088 }
3089
Tal Yacobif490a382024-05-31 09:57:36 +03003090 rc = pldm_msgbuf_init_errno(buf,
3091 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
3092 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003093 if (rc) {
3094 return rc;
3095 }
3096
3097 pldm_msgbuf_insert(buf, effecter_id);
3098
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303099 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003100}
3101
Tal Yacobide67ab62024-05-30 22:36:50 +03003102LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03003103int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
3104 size_t payload_length,
3105 uint16_t *effecter_id)
3106{
Andrew Jefferya1896962025-03-03 21:41:25 +10303107 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003108 int rc;
3109
3110 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03003111 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03003112 }
3113
Tal Yacobif490a382024-05-31 09:57:36 +03003114 rc = pldm_msgbuf_init_errno(
3115 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3116 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003117 if (rc) {
3118 return rc;
3119 }
3120
3121 pldm_msgbuf_extract_p(buf, effecter_id);
3122
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303123 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003124}
3125
Tal Yacobide67ab62024-05-30 22:36:50 +03003126LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03003127int decode_get_state_effecter_states_resp(
3128 const struct pldm_msg *msg, size_t payload_length,
3129 struct pldm_get_state_effecter_states_resp *resp)
3130{
Andrew Jefferya1896962025-03-03 21:41:25 +10303131 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003132 get_effecter_state_field *field;
3133 int rc;
3134 int i;
3135
3136 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03003137 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03003138 }
3139
Tal Yacobif490a382024-05-31 09:57:36 +03003140 rc = pldm_msgbuf_init_errno(
3141 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3142 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003143 if (rc) {
3144 return rc;
3145 }
3146
3147 rc = pldm_msgbuf_extract(buf, resp->completion_code);
3148 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303149 return pldm_msgbuf_discard(buf, rc);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003150 }
3151
3152 if (PLDM_SUCCESS != resp->completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303153 return pldm_msgbuf_complete(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003154 }
3155
3156 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
3157 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303158 return pldm_msgbuf_discard(buf, rc);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003159 }
3160
3161 uint8_t comp_effecter_count = resp->comp_effecter_count;
3162
3163 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
3164 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303165 return pldm_msgbuf_discard(buf, -EBADMSG);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003166 }
3167
3168 for (i = 0, field = resp->field; i < comp_effecter_count;
3169 i++, field++) {
3170 pldm_msgbuf_extract(buf, field->effecter_op_state);
3171 pldm_msgbuf_extract(buf, field->pending_state);
3172 pldm_msgbuf_extract(buf, field->present_state);
3173 }
3174
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303175 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003176}
3177
Tal Yacobide67ab62024-05-30 22:36:50 +03003178LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03003179int encode_get_state_effecter_states_resp(
3180 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
3181 struct pldm_msg *msg, size_t payload_length)
3182{
Andrew Jefferya1896962025-03-03 21:41:25 +10303183 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003184 get_effecter_state_field *field;
3185 int rc;
3186 int i;
3187
3188 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03003189 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03003190 }
3191
3192 uint8_t comp_effecter_count = resp->comp_effecter_count;
3193
3194 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
3195 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03003196 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03003197 }
3198
3199 struct pldm_header_info header = { 0 };
3200 header.msg_type = PLDM_RESPONSE;
3201 header.instance = instance_id;
3202 header.pldm_type = PLDM_PLATFORM;
3203 header.command = PLDM_GET_STATE_EFFECTER_STATES;
3204
Tal Yacobif490a382024-05-31 09:57:36 +03003205 rc = pack_pldm_header_errno(&header, &msg->hdr);
3206 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03003207 return rc;
3208 }
3209
Tal Yacobif490a382024-05-31 09:57:36 +03003210 rc = pldm_msgbuf_init_errno(
3211 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3212 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003213 if (rc) {
3214 return rc;
3215 }
3216
3217 pldm_msgbuf_insert(buf, resp->completion_code);
3218 pldm_msgbuf_insert(buf, comp_effecter_count);
3219
3220 for (i = 0, field = resp->field; i < comp_effecter_count;
3221 i++, field++) {
3222 pldm_msgbuf_insert(buf, field->effecter_op_state);
3223 pldm_msgbuf_insert(buf, field->pending_state);
3224 pldm_msgbuf_insert(buf, field->present_state);
3225 }
3226
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303227 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003228}
Thu Nguyendacfa352024-06-22 09:53:15 +00003229
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003230LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003231int decode_entity_auxiliary_names_pdr(
3232 const void *data, size_t data_length,
3233 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3234{
Andrew Jefferya1896962025-03-03 21:41:25 +10303235 PLDM_MSGBUF_DEFINE_P(buf);
3236 PLDM_MSGBUF_DEFINE_P(src);
3237 PLDM_MSGBUF_DEFINE_P(dst);
Thu Nguyendacfa352024-06-22 09:53:15 +00003238 size_t names_len = 0;
3239 void *names = NULL;
3240 int rc;
3241 int i;
3242
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003243 if (!data || !pdr) {
3244 return -EINVAL;
3245 }
3246
Thu Nguyendacfa352024-06-22 09:53:15 +00003247 /*
3248 * Alignment of auxiliary_name_data is an invariant as we statically assert
3249 * its behaviour in the header.
3250 */
3251 assert(!((uintptr_t)pdr->auxiliary_name_data &
3252 (alignof(pldm_utf16be) - 1)));
3253
3254 /* Reject any lengths that are obviously invalid */
3255 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3256 return -EINVAL;
3257 }
3258
3259 rc = pldm_msgbuf_init_errno(
3260 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3261 data_length);
3262 if (rc) {
3263 return rc;
3264 }
3265
Andrew Jeffery329176a2024-09-26 22:38:24 +09303266 rc = pldm_msgbuf_extract_value_pdr_hdr(
3267 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
Thu Nguyendacfa352024-06-22 09:53:15 +00003268 data_length);
3269 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303270 return pldm_msgbuf_discard(buf, rc);
Thu Nguyendacfa352024-06-22 09:53:15 +00003271 }
3272
3273 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3274 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3275 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3276 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3277 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3278 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303279 return pldm_msgbuf_discard(buf, rc);
Thu Nguyendacfa352024-06-22 09:53:15 +00003280 }
3281
3282 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3283 if (rc < 0) {
3284 return rc;
3285 }
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003286 assert(names);
Thu Nguyendacfa352024-06-22 09:53:15 +00003287
Andrew Jefferya1896962025-03-03 21:41:25 +10303288 rc = pldm_msgbuf_complete_consumed(buf);
3289 if (rc) {
3290 return rc;
3291 }
3292
Thu Nguyendacfa352024-06-22 09:53:15 +00003293 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3294
3295 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3296 pdr->auxiliary_name_data,
3297 pdr->auxiliary_name_data_size);
3298 if (rc < 0) {
3299 return rc;
3300 }
3301
3302 /*
3303 * Below we do two passes over the same region. This is to first pack the
3304 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3305 * to maintain appropriate alignment.
3306 */
3307
3308 /* Initialise for the first pass to extract the UTF16-BE name strings */
3309 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3310 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303311 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003312 }
3313
3314 for (i = 0; i < pdr->name_string_count; i++) {
3315 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003316 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3317 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303318 goto cleanup_msgbuf_src;
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003319 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003320 }
3321
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303322 rc = pldm_msgbuf_complete_consumed(src);
Thu Nguyendacfa352024-06-22 09:53:15 +00003323 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303324 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003325 }
3326
3327 /* Reinitialise for the second pass to extract the ASCII tag strings */
3328 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3329 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303330 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003331 }
3332
3333 for (i = 0; i < pdr->name_string_count; i++) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003334 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3335 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303336 goto cleanup_msgbuf_src;
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003337 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003338 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3339 }
3340
Andrew Jefferya1896962025-03-03 21:41:25 +10303341 rc = pldm_msgbuf_complete(src);
3342 if (rc) {
3343 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003344 }
3345
Andrew Jefferya1896962025-03-03 21:41:25 +10303346 return pldm_msgbuf_complete(dst);
3347
3348cleanup_msgbuf_src:
3349 rc = pldm_msgbuf_discard(src, rc);
3350cleanup_msgbuf_dst:
3351 return pldm_msgbuf_discard(dst, rc);
Thu Nguyendacfa352024-06-22 09:53:15 +00003352}
3353
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003354LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003355int decode_pldm_entity_auxiliary_names_pdr_index(
3356 struct pldm_entity_auxiliary_names_pdr *pdr)
3357{
Andrew Jefferya1896962025-03-03 21:41:25 +10303358 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyendacfa352024-06-22 09:53:15 +00003359 int rc;
3360 int i;
3361
3362 if (!pdr) {
3363 return -EINVAL;
3364 }
3365
3366 if (pdr->name_string_count == 0 && pdr->names) {
3367 return -EINVAL;
3368 }
3369
3370 if (pdr->name_string_count > 0 && !pdr->names) {
3371 return -EINVAL;
3372 }
3373
3374 if (pdr->name_string_count == 0) {
3375 return 0;
3376 }
3377
3378 /*
3379 * Minimum size is one NUL for each member of each entry
3380 *
3381 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3382 * states the following:
3383 *
3384 * > A null-terminated ISO646 ASCII string ...
3385 * >
3386 * > special value: null string = 0x0000 = unspecified.
3387 *
3388 * Until proven otherwise we will assume the "0x0000" is a
3389 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3390 * represented by a single byte.
3391 */
3392 rc = pldm_msgbuf_init_errno(
3393 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3394 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3395 if (rc) {
3396 return rc;
3397 }
3398
3399 for (i = 0; i < pdr->name_string_count; i++) {
3400 void *loc = NULL;
3401 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3402 pdr->names[i].name = loc;
3403 }
3404
3405 for (i = 0; i < pdr->name_string_count; i++) {
3406 void *loc = NULL;
3407 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3408 pdr->names[i].tag = loc;
3409 }
3410
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303411 return pldm_msgbuf_complete_consumed(buf);
Thu Nguyendacfa352024-06-22 09:53:15 +00003412}
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003413
Thu Nguyen3559aa12024-08-29 00:13:38 +00003414LIBPLDM_ABI_STABLE
Thu Nguyen02903032024-09-03 06:39:50 +00003415int decode_pldm_platform_cper_event(const void *event_data,
3416 size_t event_data_length,
3417 struct pldm_platform_cper_event *cper_event,
3418 size_t cper_event_length)
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003419{
Andrew Jefferya1896962025-03-03 21:41:25 +10303420 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003421 int rc;
3422
3423 if (!cper_event || !event_data) {
3424 return -EINVAL;
3425 }
3426
3427 if (cper_event_length < sizeof(*cper_event)) {
3428 return -EINVAL;
3429 }
3430
3431 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3432 event_data, event_data_length);
3433 if (rc) {
3434 return rc;
3435 }
3436
3437 pldm_msgbuf_extract(buf, cper_event->format_version);
3438 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3439 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303440 return pldm_msgbuf_discard(buf, rc);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003441 }
3442 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3443 cper_event->format_type !=
3444 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303445 return pldm_msgbuf_discard(buf, -EPROTO);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003446 }
3447
3448 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3449 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303450 return pldm_msgbuf_discard(buf, rc);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003451 }
3452
3453 if (cper_event->event_data_length >
3454 (cper_event_length - sizeof(*cper_event))) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303455 return pldm_msgbuf_discard(buf, -EOVERFLOW);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003456 }
3457
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003458 rc = pldm_msgbuf_extract_array_uint8(
3459 buf, cper_event->event_data_length, cper_event->event_data,
3460 cper_event_length - sizeof(*cper_event));
3461 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303462 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003463 }
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003464
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303465 return pldm_msgbuf_complete_consumed(buf);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003466}
3467
Thu Nguyen3559aa12024-08-29 00:13:38 +00003468LIBPLDM_ABI_STABLE
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003469uint8_t *
3470pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3471{
3472 return event->event_data;
3473}
Chau Lyed4ad702025-03-13 04:12:04 +00003474
Chau Ly26c8eb22025-07-30 06:56:33 +00003475LIBPLDM_ABI_STABLE
Chau Ly7c655302025-08-13 05:16:52 +00003476int decode_pldm_platform_file_descriptor_pdr(
3477 const void *data, size_t data_length,
3478 struct pldm_platform_file_descriptor_pdr *pdr)
Chau Lyed4ad702025-03-13 04:12:04 +00003479{
3480 PLDM_MSGBUF_DEFINE_P(buf);
3481 int rc;
3482
3483 if (!data || !pdr) {
3484 return -EINVAL;
3485 }
3486
3487 rc = pldm_msgbuf_init_errno(buf,
3488 PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
3489 data, data_length);
3490 if (rc) {
3491 return rc;
3492 }
3493
3494 rc = pldm_msgbuf_extract_value_pdr_hdr(
3495 buf, &pdr->hdr, PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
3496 data_length);
3497 if (rc) {
3498 return pldm_msgbuf_discard(buf, rc);
3499 }
3500
3501 pldm_msgbuf_extract(buf, pdr->terminus_handle);
3502 pldm_msgbuf_extract(buf, pdr->file_identifier);
3503 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3504 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3505 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3506 pldm_msgbuf_extract(buf, pdr->superior_directory_file_identifier);
3507 pldm_msgbuf_extract(buf, pdr->file_classification);
3508 pldm_msgbuf_extract(buf, pdr->oem_file_classification);
3509 pldm_msgbuf_extract(buf, pdr->file_capabilities.value);
3510 pldm_msgbuf_extract(buf, pdr->file_version.alpha);
3511 pldm_msgbuf_extract(buf, pdr->file_version.update);
3512 pldm_msgbuf_extract(buf, pdr->file_version.minor);
3513 pldm_msgbuf_extract(buf, pdr->file_version.major);
3514 pldm_msgbuf_extract(buf, pdr->file_maximum_size);
3515 pldm_msgbuf_extract(buf, pdr->file_maximum_file_descriptor_count);
3516 rc = pldm_msgbuf_extract_uint8_to_size(buf, pdr->file_name.length);
3517 if (rc) {
3518 return pldm_msgbuf_discard(buf, rc);
3519 }
3520
3521 pldm_msgbuf_span_required(buf, pdr->file_name.length,
3522 (void **)&pdr->file_name.ptr);
3523
3524 pdr->oem_file_classification_name.length = 0;
3525
3526 if (pdr->oem_file_classification) {
3527 rc = pldm_msgbuf_extract_uint8_to_size(
3528 buf, pdr->oem_file_classification_name.length);
3529 if (rc) {
3530 return pldm_msgbuf_discard(buf, rc);
3531 }
3532
3533 pldm_msgbuf_span_required(
3534 buf, pdr->oem_file_classification_name.length,
3535 (void **)&pdr->oem_file_classification_name.ptr);
3536 }
3537
3538 return pldm_msgbuf_complete_consumed(buf);
3539}