blob: 18de641a8c05eeafa63bee6ffae7c1c9f65b556e [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
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930396LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930397int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930398 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
399 const uint8_t *update_time, const uint8_t *oem_update_time,
400 uint32_t record_count, uint32_t repository_size,
401 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
402 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930403{
404 if (msg == NULL) {
405 return PLDM_ERROR_INVALID_DATA;
406 }
407
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930408 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930409 header.msg_type = PLDM_RESPONSE;
410 header.instance = instance_id;
411 header.pldm_type = PLDM_PLATFORM;
412 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
413
414 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
415 if (rc != PLDM_SUCCESS) {
416 return rc;
417 }
418
419 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930420 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930421 response->completion_code = completion_code;
422
423 if (response->completion_code == PLDM_SUCCESS) {
424 response->repository_state = repository_state;
425 if (update_time != NULL) {
426 memcpy(response->update_time, update_time,
427 PLDM_TIMESTAMP104_SIZE);
428 }
429 if (oem_update_time != NULL) {
430 memcpy(response->oem_update_time, oem_update_time,
431 PLDM_TIMESTAMP104_SIZE);
432 }
433 response->record_count = htole32(record_count);
434 response->repository_size = htole32(repository_size);
435 response->largest_record_size = htole32(largest_record_size);
436 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930437 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930438 }
439
440 return PLDM_SUCCESS;
441}
442
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000443LIBPLDM_ABI_DEPRECATED
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800444int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930445 const struct pldm_msg *msg, size_t payload_length,
446 uint8_t *completion_code, uint8_t *repository_state,
447 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
448 uint32_t *repository_size, uint32_t *largest_record_size,
449 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800450{
Andrew Jefferya1896962025-03-03 21:41:25 +1030451 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930452 int rc;
453
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800454 if (msg == NULL || completion_code == NULL ||
455 repository_state == NULL || update_time == NULL ||
456 oem_update_time == NULL || record_count == NULL ||
457 repository_size == NULL || largest_record_size == NULL ||
458 data_transfer_handle_timeout == NULL) {
459 return PLDM_ERROR_INVALID_DATA;
460 }
461
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930462 rc = pldm_msgbuf_init_errno(buf,
463 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
464 msg->payload, payload_length);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930465 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930466 return pldm_xlate_errno(rc);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930467 }
468
Andrew Jefferya1896962025-03-03 21:41:25 +1030469 rc = pldm_msgbuf_extract_p(buf, completion_code);
470 if (rc) {
471 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
472 }
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800473 if (PLDM_SUCCESS != *completion_code) {
474 return PLDM_SUCCESS;
475 }
476
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930477 rc = pldm_msgbuf_extract_p(buf, repository_state);
478 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030479 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930480 }
481
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800482 if (*repository_state > PLDM_FAILED) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030483 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800484 }
485
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000486 /* NOTE: Memory safety */
487 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
488 PLDM_TIMESTAMP104_SIZE);
489 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030490 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000491 }
492
493 /* NOTE: Memory safety */
494 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
495 oem_update_time, PLDM_TIMESTAMP104_SIZE);
496 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030497 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000498 }
499
Andrew Jeffery66c77232024-04-24 11:42:02 +0930500 pldm_msgbuf_extract_p(buf, record_count);
501 pldm_msgbuf_extract_p(buf, repository_size);
502 pldm_msgbuf_extract_p(buf, largest_record_size);
503 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800504
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030505 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930506 if (rc) {
507 return pldm_xlate_errno(rc);
508 }
509
510 return PLDM_SUCCESS;
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800511}
512
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000513LIBPLDM_ABI_TESTING
514int decode_get_pdr_repository_info_resp_safe(
515 const struct pldm_msg *msg, size_t payload_length,
516 struct pldm_pdr_repository_info_resp *resp)
517{
Andrew Jefferya1896962025-03-03 21:41:25 +1030518 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000519 int rc;
520
521 if (msg == NULL || resp == NULL) {
522 return -EINVAL;
523 }
524
525 rc = pldm_msg_has_error(msg, payload_length);
526 if (rc) {
527 resp->completion_code = rc;
528 return 0;
529 }
530
531 rc = pldm_msgbuf_init_errno(buf,
532 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
533 msg->payload, payload_length);
534 if (rc) {
535 return rc;
536 }
537
538 rc = pldm_msgbuf_extract(buf, resp->completion_code);
539 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030540 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000541 }
542
543 pldm_msgbuf_extract(buf, resp->repository_state);
544
545 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
546 resp->update_time,
547 sizeof(resp->update_time));
548 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030549 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000550 }
551
552 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
553 resp->oem_update_time,
554 sizeof(resp->oem_update_time));
555 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030556 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000557 }
558
559 pldm_msgbuf_extract(buf, resp->record_count);
560 pldm_msgbuf_extract(buf, resp->repository_size);
561 pldm_msgbuf_extract(buf, resp->largest_record_size);
562 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
563
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030564 return pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000565}
566
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930567LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930568int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
569 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
570 uint16_t request_cnt, uint16_t record_chg_num,
571 struct pldm_msg *msg, size_t payload_length)
572{
573 if (msg == NULL) {
574 return PLDM_ERROR_INVALID_DATA;
575 }
576
577 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
578 return PLDM_ERROR_INVALID_LENGTH;
579 }
580
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930581 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930582 header.msg_type = PLDM_REQUEST;
583 header.instance = instance_id;
584 header.pldm_type = PLDM_PLATFORM;
585 header.command = PLDM_GET_PDR;
586
587 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
588 if (rc != PLDM_SUCCESS) {
589 return rc;
590 }
591
592 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930593 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930594 request->record_handle = htole32(record_hndl);
595 request->data_transfer_handle = htole32(data_transfer_hndl);
596 request->transfer_op_flag = transfer_op_flag;
597 request->request_count = htole16(request_cnt);
598 request->record_change_number = htole16(record_chg_num);
599
600 return PLDM_SUCCESS;
601}
602
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000603LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930604int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
605 uint8_t *completion_code, uint32_t *next_record_hndl,
606 uint32_t *next_data_transfer_hndl,
607 uint8_t *transfer_flag, uint16_t *resp_cnt,
608 uint8_t *record_data, size_t record_data_length,
609 uint8_t *transfer_crc)
610{
Andrew Jefferya1896962025-03-03 21:41:25 +1030611 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930612 int rc;
613
Andrew Jeffery9c766792022-08-10 23:12:49 +0930614 if (msg == NULL || completion_code == NULL ||
615 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
616 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
617 return PLDM_ERROR_INVALID_DATA;
618 }
619
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930620 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
621 msg->payload, payload_length);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930622 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930623 return pldm_xlate_errno(rc);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930624 }
625
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930626 rc = pldm_msgbuf_extract_p(buf, completion_code);
627 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030628 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930629 }
630
Andrew Jeffery9c766792022-08-10 23:12:49 +0930631 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030632 return pldm_msgbuf_complete(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930633 }
634
Andrew Jeffery66c77232024-04-24 11:42:02 +0930635 pldm_msgbuf_extract_p(buf, next_record_hndl);
636 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
637 pldm_msgbuf_extract_p(buf, transfer_flag);
638 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930639 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030640 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930641 }
642
643 if (*resp_cnt > 0 && record_data != NULL) {
644 if (record_data_length < *resp_cnt) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030645 return pldm_msgbuf_discard(buf,
646 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930647 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000648 /* NOTE: Memory safety */
649 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
650 *resp_cnt);
651 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030652 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000653 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930654 }
655
656 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930657 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930658 }
659
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030660 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930661 if (rc) {
662 return pldm_xlate_errno(rc);
663 }
664
665 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930666}
667
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000668LIBPLDM_ABI_TESTING
669int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
670 struct pldm_get_pdr_resp *resp, size_t resp_len,
671 uint8_t *transfer_crc)
672{
Andrew Jefferya1896962025-03-03 21:41:25 +1030673 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000674 int rc;
675
676 if (msg == NULL || resp == NULL || transfer_crc == NULL) {
677 return -EINVAL;
678 }
679
680 rc = pldm_msg_has_error(msg, payload_length);
681 if (rc) {
682 resp->completion_code = rc;
683 return 0;
684 }
685
686 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
687 msg->payload, payload_length);
688 if (rc) {
689 return rc;
690 }
691
692 pldm_msgbuf_extract(buf, resp->completion_code);
693 pldm_msgbuf_extract(buf, resp->next_record_handle);
694 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
695
696 rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
697 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030698 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000699 }
700
701 rc = pldm_msgbuf_extract(buf, resp->response_count);
702 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030703 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000704 }
705
706 rc = pldm_msgbuf_extract_array(
707 buf, resp->response_count, resp->record_data,
708 resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
709 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030710 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000711 }
712
713 if (resp->transfer_flag == PLDM_END) {
714 pldm_msgbuf_extract_p(buf, transfer_crc);
715 }
716
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030717 return pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000718}
719
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930720LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930721int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
722 size_t payload_length,
723 uint16_t *effecter_id,
724 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930725 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930726{
Andrew Jefferya1896962025-03-03 21:41:25 +1030727 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930728 int rc;
729
Andrew Jeffery9c766792022-08-10 23:12:49 +0930730 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
731 effecter_value == NULL) {
732 return PLDM_ERROR_INVALID_DATA;
733 }
734
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930735 rc = pldm_msgbuf_init_errno(
736 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
737 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930738 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930739 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930740 }
741
Andrew Jeffery66c77232024-04-24 11:42:02 +0930742 pldm_msgbuf_extract_p(buf, effecter_id);
743 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930744 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030745 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930746 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930747
748 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030749 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930750 }
751
Andrew Jeffery3884c442023-04-12 11:13:24 +0930752 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
753 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930754
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030755 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930756 if (rc) {
757 return pldm_xlate_errno(rc);
758 }
759
760 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930761}
762
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930763LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930764int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
765 uint8_t completion_code,
766 struct pldm_msg *msg,
767 size_t payload_length)
768{
769 if (msg == NULL) {
770 return PLDM_ERROR_INVALID_DATA;
771 }
772
773 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
774 return PLDM_ERROR_INVALID_LENGTH;
775 }
776
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930777 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930778 header.msg_type = PLDM_RESPONSE;
779 header.instance = instance_id;
780 header.pldm_type = PLDM_PLATFORM;
781 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
782
783 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
784 if (rc != PLDM_SUCCESS) {
785 return rc;
786 }
787
788 msg->payload[0] = completion_code;
789
790 return rc;
791}
792
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930793LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930794int encode_set_numeric_effecter_value_req(uint8_t instance_id,
795 uint16_t effecter_id,
796 uint8_t effecter_data_size,
797 const uint8_t *effecter_value,
798 struct pldm_msg *msg,
799 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930800{
801 if (msg == NULL || effecter_value == NULL) {
802 return PLDM_ERROR_INVALID_DATA;
803 }
804
805 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
806 return PLDM_ERROR_INVALID_DATA;
807 }
808
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930809 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930810 header.msg_type = PLDM_REQUEST;
811 header.instance = instance_id;
812 header.pldm_type = PLDM_PLATFORM;
813 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
814
815 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
816 if (rc != PLDM_SUCCESS) {
817 return rc;
818 }
819
820 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930821 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930822 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
823 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
824 if (payload_length !=
825 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
826 return PLDM_ERROR_INVALID_LENGTH;
827 }
828 request->effecter_value[0] = *effecter_value;
829 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
830 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
831 if (payload_length !=
832 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
833 return PLDM_ERROR_INVALID_LENGTH;
834 }
835
836 uint16_t val = *(uint16_t *)(effecter_value);
837 val = htole16(val);
838 memcpy(request->effecter_value, &val, sizeof(uint16_t));
839
840 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
841 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
842 if (payload_length !=
843 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
844 return PLDM_ERROR_INVALID_LENGTH;
845 }
846
847 uint32_t val = *(uint32_t *)(effecter_value);
848 val = htole32(val);
849 memcpy(request->effecter_value, &val, sizeof(uint32_t));
850 }
851
852 request->effecter_id = htole16(effecter_id);
853 request->effecter_data_size = effecter_data_size;
854
855 return PLDM_SUCCESS;
856}
857
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930858LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930859int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
860 size_t payload_length,
861 uint8_t *completion_code)
862{
863 if (msg == NULL || completion_code == NULL) {
864 return PLDM_ERROR_INVALID_DATA;
865 }
866
867 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
868 return PLDM_ERROR_INVALID_LENGTH;
869 }
870
871 *completion_code = msg->payload[0];
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 encode_get_state_sensor_readings_resp(uint8_t instance_id,
878 uint8_t completion_code,
879 uint8_t comp_sensor_count,
880 get_sensor_state_field *field,
881 struct pldm_msg *msg)
882{
883 if (msg == NULL) {
884 return PLDM_ERROR_INVALID_DATA;
885 }
886
887 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
888 return PLDM_ERROR_INVALID_DATA;
889 }
890
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930891 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930892 header.msg_type = PLDM_RESPONSE;
893 header.instance = instance_id;
894 header.pldm_type = PLDM_PLATFORM;
895 header.command = PLDM_GET_STATE_SENSOR_READINGS;
896
897 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
898 if (rc != PLDM_SUCCESS) {
899 return rc;
900 }
901
902 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930903 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930904
905 response->completion_code = completion_code;
906 response->comp_sensor_count = comp_sensor_count;
907 memcpy(response->field, field,
908 (sizeof(get_sensor_state_field) * comp_sensor_count));
909
910 return PLDM_SUCCESS;
911}
912
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930913LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930914int encode_get_state_sensor_readings_req(uint8_t instance_id,
915 uint16_t sensor_id,
916 bitfield8_t sensor_rearm,
917 uint8_t reserved, struct pldm_msg *msg)
918{
919 if (msg == NULL) {
920 return PLDM_ERROR_INVALID_DATA;
921 }
922
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930923 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930924 header.msg_type = PLDM_REQUEST;
925 header.instance = instance_id;
926 header.pldm_type = PLDM_PLATFORM;
927 header.command = PLDM_GET_STATE_SENSOR_READINGS;
928
929 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
930 if (rc != PLDM_SUCCESS) {
931 return rc;
932 }
933
934 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930935 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930936
937 request->sensor_id = htole16(sensor_id);
938 request->reserved = reserved;
939 request->sensor_rearm = sensor_rearm;
940
941 return PLDM_SUCCESS;
942}
943
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930944LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930945int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
946 size_t payload_length,
947 uint8_t *completion_code,
948 uint8_t *comp_sensor_count,
949 get_sensor_state_field *field)
950{
Andrew Jefferya1896962025-03-03 21:41:25 +1030951 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930952 uint8_t i;
953 int rc;
954
Andrew Jeffery9c766792022-08-10 23:12:49 +0930955 if (msg == NULL || completion_code == NULL ||
956 comp_sensor_count == NULL || field == NULL) {
957 return PLDM_ERROR_INVALID_DATA;
958 }
959
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930960 rc = pldm_msgbuf_init_errno(
961 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
962 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930963 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930964 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930965 }
966
Andrew Jeffery66c77232024-04-24 11:42:02 +0930967 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930968 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030969 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930970 }
971
Andrew Jeffery9c766792022-08-10 23:12:49 +0930972 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030973 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930974 }
975
Andrew Jeffery66c77232024-04-24 11:42:02 +0930976 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930977 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030978 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930979 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930980
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930981 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jefferya1896962025-03-03 21:41:25 +1030982 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930983 }
984
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930985 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930986 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
987 pldm_msgbuf_extract(buf, field[i].present_state);
988 pldm_msgbuf_extract(buf, field[i].previous_state);
989 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930990 }
991
Andrew Jeffery70d21c92025-03-05 12:59:42 +1030992 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930993 if (rc) {
994 return pldm_xlate_errno(rc);
995 }
996
997 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930998}
999
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301000LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301001int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
1002 size_t payload_length,
1003 uint16_t *sensor_id,
1004 bitfield8_t *sensor_rearm,
1005 uint8_t *reserved)
1006{
Andrew Jefferya1896962025-03-03 21:41:25 +10301007 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301008 int rc;
1009
Andrew Jeffery9c766792022-08-10 23:12:49 +09301010 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
1011 return PLDM_ERROR_INVALID_DATA;
1012 }
1013
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301014 rc = pldm_msgbuf_init_errno(buf,
1015 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
1016 msg->payload, payload_length);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301017 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301018 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301019 }
1020
Andrew Jeffery66c77232024-04-24 11:42:02 +09301021 pldm_msgbuf_extract_p(buf, sensor_id);
1022 pldm_msgbuf_extract(buf, sensor_rearm->byte);
1023 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301024
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301025 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301026 if (rc) {
1027 return pldm_xlate_errno(rc);
1028 }
1029
1030 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301031}
1032
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301033LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301034int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301035 struct pldm_sensor_event_data *const event_data,
1036 const size_t event_data_size, const uint16_t sensor_id,
1037 const enum sensor_event_class_states sensor_event_class,
1038 const uint8_t sensor_offset, const uint8_t event_state,
1039 const uint8_t previous_event_state,
1040 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301041{
1042 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301043 (sizeof(*event_data) - sizeof(event_data->event_class) +
1044 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301045
1046 if (!event_data) {
1047 return PLDM_SUCCESS;
1048 }
1049
1050 if (event_data_size < *actual_event_data_size) {
1051 *actual_event_data_size = 0;
1052 return PLDM_ERROR_INVALID_LENGTH;
1053 }
1054
1055 event_data->sensor_id = htole16(sensor_id);
1056 event_data->sensor_event_class_type = sensor_event_class;
1057
1058 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301059 (struct pldm_sensor_event_state_sensor_state *)
1060 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301061
1062 state_data->sensor_offset = sensor_offset;
1063 state_data->event_state = event_state;
1064 state_data->previous_event_state = previous_event_state;
1065
1066 return PLDM_SUCCESS;
1067}
1068
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301069LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301070int decode_platform_event_message_req(const struct pldm_msg *msg,
1071 size_t payload_length,
1072 uint8_t *format_version, uint8_t *tid,
1073 uint8_t *event_class,
1074 size_t *event_data_offset)
1075{
Andrew Jefferya1896962025-03-03 21:41:25 +10301076 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301077 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301078
1079 if (msg == NULL || format_version == NULL || tid == NULL ||
1080 event_class == NULL || event_data_offset == NULL) {
1081 return PLDM_ERROR_INVALID_DATA;
1082 }
1083
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301084 rc = pldm_msgbuf_init_errno(buf,
1085 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
1086 msg->payload, payload_length);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301087 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301088 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301089 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301090
Andrew Jeffery66c77232024-04-24 11:42:02 +09301091 pldm_msgbuf_extract_p(buf, format_version);
1092 pldm_msgbuf_extract_p(buf, tid);
1093 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301094
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301095 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301096 if (rc) {
1097 return pldm_xlate_errno(rc);
1098 }
1099
Andrew Jeffery9c766792022-08-10 23:12:49 +09301100 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301101 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301102
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301103 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301104}
1105
Thu Nguyen387b10f2024-09-24 11:33:16 +00001106static int pldm_platform_poll_for_platform_event_message_validate(
1107 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1108{
1109 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1110 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1111 ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1112 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1113 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
Thu Nguyen9e16b182024-10-01 03:12:16 +00001114 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1115 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1116 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
Thu Nguyen387b10f2024-09-24 11:33:16 +00001117 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1118 return -EPROTO;
1119 }
1120
1121 return 0;
1122}
1123
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301124LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001125int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301126 const struct pldm_msg *msg, size_t payload_length,
1127 uint8_t *format_version, uint8_t *transfer_operation_flag,
1128 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001129{
Andrew Jefferya1896962025-03-03 21:41:25 +10301130 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001131 int rc;
1132
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001133 if (msg == NULL || format_version == NULL ||
1134 transfer_operation_flag == NULL || data_transfer_handle == NULL ||
1135 event_id_to_acknowledge == NULL) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001136 return PLDM_ERROR_INVALID_DATA;
1137 }
1138
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301139 rc = pldm_msgbuf_init_errno(
1140 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
1141 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001142 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301143 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001144 }
1145
Andrew Jeffery66c77232024-04-24 11:42:02 +09301146 pldm_msgbuf_extract_p(buf, format_version);
1147 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001148 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301149 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001150 }
1151 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301152 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001153 }
1154
Andrew Jeffery66c77232024-04-24 11:42:02 +09301155 pldm_msgbuf_extract_p(buf, data_transfer_handle);
1156 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001157 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301158 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001159 }
1160
Thu Nguyen387b10f2024-09-24 11:33:16 +00001161 rc = pldm_platform_poll_for_platform_event_message_validate(
1162 *transfer_operation_flag, *event_id_to_acknowledge);
1163 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301164 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001165 }
1166
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301167 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301168 if (rc) {
1169 return pldm_xlate_errno(rc);
1170 }
1171
1172 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001173}
1174
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301175LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301176int encode_platform_event_message_resp(uint8_t instance_id,
1177 uint8_t completion_code,
1178 uint8_t platform_event_status,
1179 struct pldm_msg *msg)
1180{
1181 if (msg == NULL) {
1182 return PLDM_ERROR_INVALID_DATA;
1183 }
1184
1185 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1186 return PLDM_ERROR_INVALID_DATA;
1187 }
1188
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301189 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301190 header.msg_type = PLDM_RESPONSE;
1191 header.instance = instance_id;
1192 header.pldm_type = PLDM_PLATFORM;
1193 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1194
1195 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1196 if (rc != PLDM_SUCCESS) {
1197 return rc;
1198 }
1199
1200 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301201 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301202 response->completion_code = completion_code;
1203 response->platform_event_status = platform_event_status;
1204
1205 return PLDM_SUCCESS;
1206}
1207
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301208LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001209int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301210 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1211 uint16_t event_id, uint32_t next_data_transfer_handle,
1212 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1213 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1214 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001215{
Andrew Jefferya1896962025-03-03 21:41:25 +10301216 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001217 int rc;
1218
1219 if (!msg) {
1220 return PLDM_ERROR_INVALID_DATA;
1221 }
1222
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301223 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001224 header.msg_type = PLDM_RESPONSE;
1225 header.instance = instance_id;
1226 header.pldm_type = PLDM_PLATFORM;
1227 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1228
1229 rc = pack_pldm_header(&header, &(msg->hdr));
1230 if (rc != PLDM_SUCCESS) {
1231 return rc;
1232 }
1233
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301234 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301235 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1236 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001237 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301238 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001239 }
1240
1241 pldm_msgbuf_insert(buf, completion_code);
1242 pldm_msgbuf_insert(buf, tid);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301243 rc = pldm_msgbuf_insert(buf, event_id);
1244 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301245 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301246 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001247
1248 if (event_id == 0xffff || event_id == 0x0000) {
1249 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1250 payload_length) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301251 return pldm_msgbuf_discard(buf,
1252 PLDM_ERROR_INVALID_LENGTH);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001253 }
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301254
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301255 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301256 if (rc) {
1257 return pldm_xlate_errno(rc);
1258 }
1259
1260 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001261 }
1262
1263 if ((event_data == NULL) && (event_data_size > 0)) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301264 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001265 }
1266
1267 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1268 pldm_msgbuf_insert(buf, transfer_flag);
1269 pldm_msgbuf_insert(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301270 rc = pldm_msgbuf_insert(buf, event_data_size);
1271 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301272 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301273 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001274
1275 if ((event_data_size > 0) && event_data) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001276 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
1277 event_data_size);
1278 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301279 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001280 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001281 }
1282
1283 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1284 pldm_msgbuf_insert(buf, checksum);
1285 }
1286
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301287 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301288 if (rc) {
1289 return pldm_xlate_errno(rc);
1290 }
1291
1292 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001293}
1294
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301295LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301296int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301297 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1298 uint8_t event_class, const uint8_t *event_data,
1299 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301300
1301{
1302 if (format_version != 1) {
1303 return PLDM_ERROR_INVALID_DATA;
1304 }
1305
1306 if (msg == NULL || event_data == NULL) {
1307 return PLDM_ERROR_INVALID_DATA;
1308 }
1309
1310 if (event_data_length == 0) {
1311 return PLDM_ERROR_INVALID_DATA;
1312 }
1313
Andrew Jeffery225530a2024-09-25 13:11:43 +09301314 if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1315 event_data_length) {
1316 return PLDM_ERROR_INVALID_LENGTH;
1317 }
1318
Andrew Jeffery9c766792022-08-10 23:12:49 +09301319 if (payload_length !=
1320 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1321 return PLDM_ERROR_INVALID_LENGTH;
1322 }
1323
John Chungb43a7782024-09-26 22:04:27 +08001324 if (event_class > PLDM_CPER_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001325 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301326 return PLDM_ERROR_INVALID_DATA;
1327 }
1328
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301329 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301330 header.msg_type = PLDM_REQUEST;
1331 header.instance = instance_id;
1332 header.pldm_type = PLDM_PLATFORM;
1333 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1334
1335 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1336 if (rc != PLDM_SUCCESS) {
1337 return rc;
1338 }
1339
1340 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301341 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301342 request->format_version = format_version;
1343 request->tid = tid;
1344 request->event_class = event_class;
1345 memcpy(request->event_data, event_data, event_data_length);
1346
1347 return PLDM_SUCCESS;
1348}
1349
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301350LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301351int decode_platform_event_message_resp(const struct pldm_msg *msg,
1352 size_t payload_length,
1353 uint8_t *completion_code,
1354 uint8_t *platform_event_status)
1355{
Andrew Jefferya1896962025-03-03 21:41:25 +10301356 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferye5011772023-04-13 12:06:22 +09301357 int rc;
1358
Andrew Jeffery9c766792022-08-10 23:12:49 +09301359 if (msg == NULL || completion_code == NULL ||
1360 platform_event_status == NULL) {
1361 return PLDM_ERROR_INVALID_DATA;
1362 }
1363
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301364 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1365 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301366 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301367 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301368 }
1369
Andrew Jeffery66c77232024-04-24 11:42:02 +09301370 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301371 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301372 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferye5011772023-04-13 12:06:22 +09301373 }
1374
Andrew Jeffery9c766792022-08-10 23:12:49 +09301375 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301376 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301377 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301378
Andrew Jeffery66c77232024-04-24 11:42:02 +09301379 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301380 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301381 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jefferye5011772023-04-13 12:06:22 +09301382 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301383
1384 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301385 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301386 }
1387
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301388 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301389 if (rc) {
1390 return pldm_xlate_errno(rc);
1391 }
1392
1393 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301394}
1395
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301396LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301397int encode_event_message_buffer_size_req(uint8_t instance_id,
1398 uint16_t event_receiver_max_buffer_size,
1399 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001400{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301401 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001402 header.msg_type = PLDM_REQUEST;
1403 header.instance = instance_id;
1404 header.pldm_type = PLDM_PLATFORM;
1405 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1406
1407 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1408 if (rc != PLDM_SUCCESS) {
1409 return rc;
1410 }
1411
1412 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301413 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001414 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301415 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001416
1417 return PLDM_SUCCESS;
1418}
1419
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301420LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001421int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1422 size_t payload_length,
1423 uint8_t *completion_code,
1424 uint16_t *terminus_max_buffer_size)
1425{
Andrew Jefferya1896962025-03-03 21:41:25 +10301426 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery11126902023-04-13 12:12:10 +09301427 int rc;
1428
Dung Caod6ae8982022-11-02 10:00:10 +07001429 if (msg == NULL || completion_code == NULL ||
1430 terminus_max_buffer_size == NULL) {
1431 return PLDM_ERROR_INVALID_DATA;
1432 }
1433
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301434 rc = pldm_msgbuf_init_errno(buf,
1435 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1436 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301437 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301438 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301439 }
1440
Andrew Jeffery66c77232024-04-24 11:42:02 +09301441 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301442 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301443 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery11126902023-04-13 12:12:10 +09301444 }
1445
Dung Caod6ae8982022-11-02 10:00:10 +07001446 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301447 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Dung Caod6ae8982022-11-02 10:00:10 +07001448 }
Dung Caod6ae8982022-11-02 10:00:10 +07001449
Andrew Jeffery66c77232024-04-24 11:42:02 +09301450 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001451
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301452 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301453 if (rc) {
1454 return pldm_xlate_errno(rc);
1455 }
1456
1457 return PLDM_SUCCESS;
Dung Caod6ae8982022-11-02 10:00:10 +07001458}
1459
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301460LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001461int encode_event_message_supported_req(uint8_t instance_id,
1462 uint8_t format_version,
1463 struct pldm_msg *msg)
1464{
1465 if (format_version != 1) {
1466 return PLDM_ERROR_INVALID_DATA;
1467 }
1468
1469 if (msg == NULL) {
1470 return PLDM_ERROR_INVALID_DATA;
1471 }
1472
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301473 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001474 header.msg_type = PLDM_REQUEST;
1475 header.instance = instance_id;
1476 header.pldm_type = PLDM_PLATFORM;
1477 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1478
1479 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1480 if (rc != PLDM_SUCCESS) {
1481 return rc;
1482 }
1483
1484 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301485 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001486 request->format_version = format_version;
1487
1488 return PLDM_SUCCESS;
1489}
1490
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301491LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301492int decode_event_message_supported_resp(const struct pldm_msg *msg,
1493 size_t payload_length,
1494 uint8_t *completion_code,
1495 uint8_t *synchrony_config,
1496 bitfield8_t *synchrony_config_support,
1497 uint8_t *number_event_class_returned,
1498 uint8_t *event_class,
1499 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001500{
Andrew Jefferya1896962025-03-03 21:41:25 +10301501 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301502 int i;
1503 int rc;
1504
Dung Cao1bf8c872022-11-29 05:32:58 +07001505 if (msg == NULL || completion_code == NULL ||
1506 synchrony_config == NULL || synchrony_config_support == NULL ||
1507 number_event_class_returned == NULL || event_class == NULL) {
1508 return PLDM_ERROR_INVALID_DATA;
1509 }
1510
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301511 rc = pldm_msgbuf_init_errno(buf,
1512 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1513 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301514 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301515 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301516 }
1517
Andrew Jeffery66c77232024-04-24 11:42:02 +09301518 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301519 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301520 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301521 }
1522
Dung Cao1bf8c872022-11-29 05:32:58 +07001523 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301524 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Dung Cao1bf8c872022-11-29 05:32:58 +07001525 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301526
Andrew Jeffery66c77232024-04-24 11:42:02 +09301527 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301528 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301529 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Dung Cao1bf8c872022-11-29 05:32:58 +07001530 }
1531
Dung Cao1bf8c872022-11-29 05:32:58 +07001532 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301533 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Dung Cao1bf8c872022-11-29 05:32:58 +07001534 }
1535
Andrew Jeffery66c77232024-04-24 11:42:02 +09301536 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001537
Andrew Jeffery66c77232024-04-24 11:42:02 +09301538 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301539 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301540 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Dung Cao1bf8c872022-11-29 05:32:58 +07001541 }
1542
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301543 if (*number_event_class_returned == 0) {
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301544 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301545 if (rc) {
1546 return pldm_xlate_errno(rc);
1547 }
1548
1549 return PLDM_SUCCESS;
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301550 }
1551
1552 if (event_class_count < *number_event_class_returned) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301553 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301554 }
1555
1556 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301557 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301558 }
1559
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301560 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301561 if (rc) {
1562 return pldm_xlate_errno(rc);
1563 }
1564
1565 return PLDM_SUCCESS;
Dung Cao1bf8c872022-11-29 05:32:58 +07001566}
1567
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301568LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301569int decode_sensor_event_data(const uint8_t *event_data,
1570 size_t event_data_length, uint16_t *sensor_id,
1571 uint8_t *sensor_event_class_type,
1572 size_t *event_class_data_offset)
1573{
Andrew Jefferya1896962025-03-03 21:41:25 +10301574 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301575 int rc;
1576
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001577 if (event_data == NULL || sensor_id == NULL ||
1578 sensor_event_class_type == NULL ||
1579 event_class_data_offset == NULL) {
1580 return PLDM_ERROR_INVALID_DATA;
1581 }
1582
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301583 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1584 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301585 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301586 return pldm_xlate_errno(rc);
1587 }
1588
1589 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301590 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301591 }
1592
1593 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301594 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301595
Andrew Jeffery66c77232024-04-24 11:42:02 +09301596 pldm_msgbuf_extract_p(buf, sensor_id);
1597 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301598 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301599 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301600 }
1601
1602 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301603 if (event_class_data_length !=
1604 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301605 return pldm_msgbuf_discard(buf,
1606 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301607 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301608 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301609 if (event_class_data_length !=
1610 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301611 return pldm_msgbuf_discard(buf,
1612 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301613 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301614 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301615 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301616 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301617 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301618 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301619 return pldm_msgbuf_discard(buf,
1620 PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301621 }
1622 } else {
Andrew Jefferya1896962025-03-03 21:41:25 +10301623 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301624 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301625
Andrew Jeffery9c766792022-08-10 23:12:49 +09301626 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301627 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301628
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301629 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301630 if (rc) {
1631 return pldm_xlate_errno(rc);
1632 }
1633
1634 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301635}
1636
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301637LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301638int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1639 uint8_t *present_op_state, uint8_t *previous_op_state)
1640{
Andrew Jefferya1896962025-03-03 21:41:25 +10301641 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301642 int rc;
1643
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001644 if (sensor_data == NULL || present_op_state == NULL ||
1645 previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301646 return PLDM_ERROR_INVALID_DATA;
1647 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301648
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301649 rc = pldm_msgbuf_init_errno(
1650 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1651 sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301652 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301653 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301654 }
1655
Andrew Jeffery66c77232024-04-24 11:42:02 +09301656 pldm_msgbuf_extract_p(buf, present_op_state);
1657 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301658
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301659 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301660 if (rc) {
1661 return pldm_xlate_errno(rc);
1662 }
1663
1664 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301665}
1666
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301667LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301668int decode_state_sensor_data(const uint8_t *sensor_data,
1669 size_t sensor_data_length, uint8_t *sensor_offset,
1670 uint8_t *event_state,
1671 uint8_t *previous_event_state)
1672{
Andrew Jefferya1896962025-03-03 21:41:25 +10301673 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301674 int rc;
1675
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001676 if (sensor_data == NULL || sensor_offset == NULL ||
1677 event_state == NULL || previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301678 return PLDM_ERROR_INVALID_DATA;
1679 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301680
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301681 rc = pldm_msgbuf_init_errno(
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301682 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1683 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301684 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301685 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301686 }
1687
Andrew Jeffery66c77232024-04-24 11:42:02 +09301688 pldm_msgbuf_extract_p(buf, sensor_offset);
1689 pldm_msgbuf_extract_p(buf, event_state);
1690 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301691
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301692 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301693 if (rc) {
1694 return pldm_xlate_errno(rc);
1695 }
1696
1697 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301698}
1699
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301700LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301701int decode_numeric_sensor_data(const uint8_t *sensor_data,
1702 size_t sensor_data_length, uint8_t *event_state,
1703 uint8_t *previous_event_state,
1704 uint8_t *sensor_data_size,
1705 uint32_t *present_reading)
1706{
Andrew Jefferya1896962025-03-03 21:41:25 +10301707 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301708 int rc;
1709
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001710 if (sensor_data == NULL || sensor_data_size == NULL ||
1711 event_state == NULL || previous_event_state == NULL ||
1712 present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301713 return PLDM_ERROR_INVALID_DATA;
1714 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301715
1716 if (sensor_data_length >
1717 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301718 return PLDM_ERROR_INVALID_LENGTH;
1719 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301720
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301721 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301722 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1723 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301724 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301725 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301726 }
1727
Andrew Jeffery66c77232024-04-24 11:42:02 +09301728 pldm_msgbuf_extract_p(buf, event_state);
1729 pldm_msgbuf_extract_p(buf, previous_event_state);
1730 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301731 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301732 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery155317e2023-04-13 18:36:51 +09301733 }
1734
1735 /*
1736 * The implementation below is bonkers, but it's because the function
1737 * prototype is bonkers. The `present_reading` argument should have been
1738 * a tagged union.
1739 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301740 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301741 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1742 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301743 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301744 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301745 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301746 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301747 }
1748 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1749 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301750 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301751 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301752 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301753 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301754 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301755 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301756 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301757 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301758 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301759 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301760 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301761 }
1762 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301763 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301764 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301765 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301766 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301767 break;
1768 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301769 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1770 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301771 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301772 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301773 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301774 break;
1775 }
1776 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1777 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301778 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301779 *present_reading = (uint32_t)val;
1780 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301781 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301782 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301783 default:
Andrew Jefferya1896962025-03-03 21:41:25 +10301784 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301785 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301786
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301787 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301788 if (rc) {
1789 return pldm_xlate_errno(rc);
1790 }
1791
1792 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301793}
1794
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301795LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301796int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301797 const void *pdr_data, size_t pdr_data_length,
1798 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301799{
Andrew Jefferya1896962025-03-03 21:41:25 +10301800 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301801 int rc;
1802
Andrew Jefferya1896962025-03-03 21:41:25 +10301803 if (!pdr_data || !pdr_value) {
1804 return PLDM_ERROR_INVALID_DATA;
1805 }
1806
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301807 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1808 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301809 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301810 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301811 }
1812
Andrew Jeffery329176a2024-09-26 22:38:24 +09301813 rc = pldm_msgbuf_extract_value_pdr_hdr(
1814 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301815 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301816 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301817 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301818 }
1819
Andrew Jeffery66c77232024-04-24 11:42:02 +09301820 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1821 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1822 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1823 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1824 pldm_msgbuf_extract(buf, pdr_value->container_id);
1825 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1826 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1827 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1828 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1829 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1830 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1831 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1832 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1833 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1834 pldm_msgbuf_extract(buf, pdr_value->rel);
1835 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1836 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301837
Andrew Jeffery66c77232024-04-24 11:42:02 +09301838 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301839 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301840 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301841 }
1842 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301843 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301844 }
1845
Andrew Jeffery66c77232024-04-24 11:42:02 +09301846 pldm_msgbuf_extract(buf, pdr_value->resolution);
1847 pldm_msgbuf_extract(buf, pdr_value->offset);
1848 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1849 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1850 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301851 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1852 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301853 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301854 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301855 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1856 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1857 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301858 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1859 &pdr_value->max_readable);
1860 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1861 &pdr_value->min_readable);
1862
Andrew Jeffery66c77232024-04-24 11:42:02 +09301863 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301864 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301865 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301866 }
1867 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10301868 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301869 }
1870
Andrew Jeffery66c77232024-04-24 11:42:02 +09301871 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301872 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301873 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301874 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301875 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301876 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301877 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301878 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301879 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301880 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301881 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301882 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301883 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301884 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301885 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301886 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301887 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301888 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301889 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301890
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301891 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301892 if (rc) {
1893 return pldm_xlate_errno(rc);
1894 }
1895
1896 return PLDM_SUCCESS;
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301897}
1898
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301899LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301900int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1901 uint16_t effecter_id,
1902 struct pldm_msg *msg)
1903{
1904 if (msg == NULL) {
1905 return PLDM_ERROR_INVALID_DATA;
1906 }
1907
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301908 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301909 header.msg_type = PLDM_REQUEST;
1910 header.instance = instance_id;
1911 header.pldm_type = PLDM_PLATFORM;
1912 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1913
1914 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1915 if (rc != PLDM_SUCCESS) {
1916 return rc;
1917 }
1918
1919 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301920 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301921 request->effecter_id = htole16(effecter_id);
1922
1923 return PLDM_SUCCESS;
1924}
1925
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301926LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301927int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301928 uint8_t instance_id, uint8_t completion_code,
1929 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1930 const uint8_t *pending_value, const uint8_t *present_value,
1931 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301932{
1933 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1934 return PLDM_ERROR_INVALID_DATA;
1935 }
1936
1937 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1938 return PLDM_ERROR_INVALID_DATA;
1939 }
1940
1941 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1942 return PLDM_ERROR_INVALID_DATA;
1943 }
1944
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301945 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301946 header.msg_type = PLDM_RESPONSE;
1947 header.instance = instance_id;
1948 header.pldm_type = PLDM_PLATFORM;
1949 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1950
1951 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1952 if (rc != PLDM_SUCCESS) {
1953 return rc;
1954 }
1955
1956 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301957 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301958
1959 response->completion_code = completion_code;
1960 response->effecter_data_size = effecter_data_size;
1961 response->effecter_oper_state = effecter_oper_state;
1962
1963 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1964 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1965 if (payload_length !=
1966 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1967 return PLDM_ERROR_INVALID_LENGTH;
1968 }
1969 response->pending_and_present_values[0] = *pending_value;
1970 response->pending_and_present_values[1] = *present_value;
1971
1972 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1973 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1974 if (payload_length !=
1975 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1976 return PLDM_ERROR_INVALID_LENGTH;
1977 }
1978 uint16_t val_pending = *(uint16_t *)pending_value;
1979 val_pending = htole16(val_pending);
1980 memcpy(response->pending_and_present_values, &val_pending,
1981 sizeof(uint16_t));
1982 uint16_t val_present = *(uint16_t *)present_value;
1983 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301984 memcpy((response->pending_and_present_values +
1985 sizeof(uint16_t)),
1986 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301987
1988 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1989 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1990 if (payload_length !=
1991 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1992 return PLDM_ERROR_INVALID_LENGTH;
1993 }
1994 uint32_t val_pending = *(uint32_t *)pending_value;
1995 val_pending = htole32(val_pending);
1996 memcpy(response->pending_and_present_values, &val_pending,
1997 sizeof(uint32_t));
1998 uint32_t val_present = *(uint32_t *)present_value;
1999 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302000 memcpy((response->pending_and_present_values +
2001 sizeof(uint32_t)),
2002 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302003 }
2004 return PLDM_SUCCESS;
2005}
2006
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302007LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302008int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
2009 size_t payload_length,
2010 uint16_t *effecter_id)
2011{
Andrew Jefferya1896962025-03-03 21:41:25 +10302012 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydd265822023-04-13 22:42:44 +09302013 int rc;
2014
Andrew Jeffery9c766792022-08-10 23:12:49 +09302015 if (msg == NULL || effecter_id == NULL) {
2016 return PLDM_ERROR_INVALID_DATA;
2017 }
2018
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302019 rc = pldm_msgbuf_init_errno(buf,
2020 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2021 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09302022 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302023 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302024 }
2025
Andrew Jeffery66c77232024-04-24 11:42:02 +09302026 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302027
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302028 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302029 if (rc) {
2030 return pldm_xlate_errno(rc);
2031 }
2032
2033 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302034}
2035
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302036LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302037int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2038 size_t payload_length,
2039 uint8_t *completion_code,
2040 uint8_t *effecter_data_size,
2041 uint8_t *effecter_oper_state,
2042 uint8_t *pending_value,
2043 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302044{
Andrew Jefferya1896962025-03-03 21:41:25 +10302045 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302046 int rc;
2047
Andrew Jeffery9c766792022-08-10 23:12:49 +09302048 if (msg == NULL || effecter_data_size == NULL ||
2049 effecter_oper_state == NULL || pending_value == NULL ||
2050 present_value == NULL) {
2051 return PLDM_ERROR_INVALID_DATA;
2052 }
2053
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302054 rc = pldm_msgbuf_init_errno(
2055 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2056 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302057 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302058 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302059 }
2060
Andrew Jeffery66c77232024-04-24 11:42:02 +09302061 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302062 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302063 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302064 }
2065
Andrew Jeffery9c766792022-08-10 23:12:49 +09302066 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302067 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302068 }
2069
Andrew Jeffery66c77232024-04-24 11:42:02 +09302070 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302071 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302072 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302073 }
2074
Andrew Jeffery9c766792022-08-10 23:12:49 +09302075 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302076 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302077 }
2078
Andrew Jeffery66c77232024-04-24 11:42:02 +09302079 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
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 (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302085 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302086 }
2087
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302088 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2089 pending_value);
2090 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2091 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302092
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302093 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302094 if (rc) {
2095 return pldm_xlate_errno(rc);
2096 }
2097
2098 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302099}
2100
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302101LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302102int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302103 uint8_t event_data_format, uint8_t number_of_change_records,
2104 const uint8_t *event_data_operations,
2105 const uint8_t *numbers_of_change_entries,
2106 const uint32_t *const *change_entries,
2107 struct pldm_pdr_repository_chg_event_data *event_data,
2108 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302109{
2110 if (event_data_operations == NULL ||
2111 numbers_of_change_entries == NULL || change_entries == NULL) {
2112 return PLDM_ERROR_INVALID_DATA;
2113 }
2114
2115 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302116 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302117
2118 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302119 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302120 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302121 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302122
2123 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302124 expected_size += sizeof(*change_entries[0]) *
2125 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302126 }
2127
2128 *actual_change_records_size = expected_size;
2129
2130 if (event_data == NULL) {
2131 return PLDM_SUCCESS;
2132 }
2133
2134 if (max_change_records_size < expected_size) {
2135 return PLDM_ERROR_INVALID_LENGTH;
2136 }
2137
2138 event_data->event_data_format = event_data_format;
2139 event_data->number_of_change_records = number_of_change_records;
2140
2141 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302142 (struct pldm_pdr_repository_change_record_data *)
2143 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302144
2145 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2146 record_data->event_data_operation = event_data_operations[i];
2147 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302148 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302149
2150 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2151 ++j) {
2152 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302153 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302154 }
2155
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302156 record_data =
2157 (struct pldm_pdr_repository_change_record_data
2158 *)(record_data->change_entry +
2159 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302160 }
2161
2162 return PLDM_SUCCESS;
2163}
2164
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302165LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302166int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2167 size_t event_data_size,
2168 uint8_t *event_data_format,
2169 uint8_t *number_of_change_records,
2170 size_t *change_record_data_offset)
2171{
Andrew Jefferya1896962025-03-03 21:41:25 +10302172 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302173 int rc;
2174
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002175 if (event_data == NULL || event_data_format == NULL ||
2176 number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302177 change_record_data_offset == NULL) {
2178 return PLDM_ERROR_INVALID_DATA;
2179 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302180
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302181 rc = pldm_msgbuf_init_errno(buf,
2182 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2183 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302184 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302185 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302186 }
2187
Andrew Jeffery66c77232024-04-24 11:42:02 +09302188 pldm_msgbuf_extract_p(buf, event_data_format);
2189 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302190
Andrew Jeffery9c766792022-08-10 23:12:49 +09302191 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302192 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302193
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302194 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302195 if (rc) {
2196 return pldm_xlate_errno(rc);
2197 }
2198
2199 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302200}
2201
Thu Nguyenf874b382024-07-24 11:22:34 +00002202LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00002203int decode_pldm_message_poll_event_data(
2204 const void *event_data, size_t event_data_length,
2205 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07002206{
Andrew Jefferya1896962025-03-03 21:41:25 +10302207 PLDM_MSGBUF_DEFINE_P(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002208 int rc;
2209
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002210 if (!event_data || !poll_event) {
Thu Nguyen7739d122024-07-26 11:36:39 +00002211 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07002212 }
2213
Thu Nguyen7739d122024-07-26 11:36:39 +00002214 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2215 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002216 if (rc) {
2217 return rc;
2218 }
2219
Thu Nguyen7739d122024-07-26 11:36:39 +00002220 pldm_msgbuf_extract(buf, poll_event->format_version);
2221 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07002222 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302223 return pldm_msgbuf_discard(buf, rc);
Dung Cao7c250342022-11-16 22:40:37 +07002224 }
2225
Thu Nguyen7739d122024-07-26 11:36:39 +00002226 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302227 return pldm_msgbuf_discard(buf, -EPROTO);
Dung Cao7c250342022-11-16 22:40:37 +07002228 }
2229
Thu Nguyen7739d122024-07-26 11:36:39 +00002230 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002231
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302232 return pldm_msgbuf_complete_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002233}
2234
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302235LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00002236int encode_pldm_message_poll_event_data(
2237 const struct pldm_message_poll_event *poll_event, void *event_data,
2238 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07002239{
Andrew Jefferya1896962025-03-03 21:41:25 +10302240 PLDM_MSGBUF_DEFINE_P(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002241 int rc;
2242
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002243 if (poll_event == NULL || event_data == NULL) {
2244 return -EINVAL;
2245 }
2246
Thu Nguyen7739d122024-07-26 11:36:39 +00002247 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2248 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002249 }
2250
Thu Nguyen7739d122024-07-26 11:36:39 +00002251 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2252 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002253 if (rc) {
2254 return rc;
2255 }
Thu Nguyen7739d122024-07-26 11:36:39 +00002256 pldm_msgbuf_insert(buf, poll_event->format_version);
2257 pldm_msgbuf_insert(buf, poll_event->event_id);
2258 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002259
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302260 return pldm_msgbuf_complete_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002261}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302262
2263LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302264int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302265 const uint8_t *change_record_data, size_t change_record_data_size,
2266 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
2267 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302268{
Andrew Jefferya1896962025-03-03 21:41:25 +10302269 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302270 int rc;
2271
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002272 if (change_record_data == NULL || event_data_operation == NULL ||
2273 number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302274 change_entry_data_offset == NULL) {
2275 return PLDM_ERROR_INVALID_DATA;
2276 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302277
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302278 rc = pldm_msgbuf_init_errno(
2279 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2280 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302281 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302282 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302283 }
2284
Andrew Jeffery66c77232024-04-24 11:42:02 +09302285 pldm_msgbuf_extract_p(buf, event_data_operation);
2286 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302287
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302288 *change_entry_data_offset = sizeof(*event_data_operation) +
2289 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302290
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302291 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302292 if (rc) {
2293 return pldm_xlate_errno(rc);
2294 }
2295
2296 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302297}
2298
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302299LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302300int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2301 uint8_t rearm_event_state,
2302 struct pldm_msg *msg)
2303{
2304 if (msg == NULL) {
2305 return PLDM_ERROR_INVALID_DATA;
2306 }
2307
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302308 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302309 header.msg_type = PLDM_REQUEST;
2310 header.instance = instance_id;
2311 header.pldm_type = PLDM_PLATFORM;
2312 header.command = PLDM_GET_SENSOR_READING;
2313
2314 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2315 if (rc != PLDM_SUCCESS) {
2316 return rc;
2317 }
2318
2319 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302320 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302321
2322 request->sensor_id = htole16(sensor_id);
2323 request->rearm_event_state = rearm_event_state;
2324
2325 return PLDM_SUCCESS;
2326}
2327
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302328LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302329int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302330 const struct pldm_msg *msg, size_t payload_length,
2331 uint8_t *completion_code, uint8_t *sensor_data_size,
2332 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2333 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2334 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302335{
Andrew Jefferya1896962025-03-03 21:41:25 +10302336 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302337 int rc;
2338
Andrew Jeffery9c766792022-08-10 23:12:49 +09302339 if (msg == NULL || completion_code == NULL ||
2340 sensor_data_size == NULL || sensor_operational_state == NULL ||
2341 sensor_event_message_enable == NULL || present_state == NULL ||
2342 previous_state == NULL || event_state == NULL ||
2343 present_reading == NULL) {
2344 return PLDM_ERROR_INVALID_DATA;
2345 }
2346
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302347 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2348 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302349 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302350 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302351 }
2352
Andrew Jeffery66c77232024-04-24 11:42:02 +09302353 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302354 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302355 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery840b1402023-04-13 23:54:44 +09302356 }
2357
Andrew Jeffery9c766792022-08-10 23:12:49 +09302358 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302359 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302360 }
2361
Andrew Jeffery66c77232024-04-24 11:42:02 +09302362 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302363 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302364 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302365 }
2366
Andrew Jeffery840b1402023-04-13 23:54:44 +09302367 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302368 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302369 }
2370
Andrew Jeffery66c77232024-04-24 11:42:02 +09302371 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2372 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2373 pldm_msgbuf_extract_p(buf, present_state);
2374 pldm_msgbuf_extract_p(buf, previous_state);
2375 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302376
Andrew Jeffery840b1402023-04-13 23:54:44 +09302377 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2378 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302379
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302380 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302381 if (rc) {
2382 return pldm_xlate_errno(rc);
2383 }
2384
2385 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302386}
2387
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302388LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302389int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2390 uint8_t sensor_data_size,
2391 uint8_t sensor_operational_state,
2392 uint8_t sensor_event_message_enable,
2393 uint8_t present_state,
2394 uint8_t previous_state, uint8_t event_state,
2395 const uint8_t *present_reading,
2396 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302397{
2398 if (msg == NULL || present_reading == NULL) {
2399 return PLDM_ERROR_INVALID_DATA;
2400 }
2401
2402 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2403 return PLDM_ERROR_INVALID_DATA;
2404 }
2405
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302406 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302407 header.msg_type = PLDM_RESPONSE;
2408 header.instance = instance_id;
2409 header.pldm_type = PLDM_PLATFORM;
2410 header.command = PLDM_GET_SENSOR_READING;
2411
2412 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2413 if (rc != PLDM_SUCCESS) {
2414 return rc;
2415 }
2416
2417 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302418 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302419
2420 response->completion_code = completion_code;
2421 response->sensor_data_size = sensor_data_size;
2422 response->sensor_operational_state = sensor_operational_state;
2423 response->sensor_event_message_enable = sensor_event_message_enable;
2424 response->present_state = present_state;
2425 response->previous_state = previous_state;
2426 response->event_state = event_state;
2427
2428 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2429 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2430 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2431 return PLDM_ERROR_INVALID_LENGTH;
2432 }
2433 response->present_reading[0] = *present_reading;
2434
2435 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2436 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2437 if (payload_length !=
2438 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2439 return PLDM_ERROR_INVALID_LENGTH;
2440 }
2441 uint16_t val = *(uint16_t *)present_reading;
2442 val = htole16(val);
2443 memcpy(response->present_reading, &val, 2);
2444
2445 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2446 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2447 if (payload_length !=
2448 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2449 return PLDM_ERROR_INVALID_LENGTH;
2450 }
2451 uint32_t val = *(uint32_t *)present_reading;
2452 val = htole32(val);
2453 memcpy(response->present_reading, &val, 4);
2454 }
2455
2456 return PLDM_SUCCESS;
2457}
2458
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302459LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302460int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2461 size_t payload_length, uint16_t *sensor_id,
2462 uint8_t *rearm_event_state)
2463{
Andrew Jefferya1896962025-03-03 21:41:25 +10302464 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302465 int rc;
2466
Andrew Jeffery9c766792022-08-10 23:12:49 +09302467 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2468 return PLDM_ERROR_INVALID_DATA;
2469 }
2470
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302471 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2472 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302473 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302474 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302475 }
2476
Andrew Jeffery66c77232024-04-24 11:42:02 +09302477 pldm_msgbuf_extract_p(buf, sensor_id);
2478 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302479
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302480 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302481 if (rc) {
2482 return pldm_xlate_errno(rc);
2483 }
2484
2485 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302486}
2487
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302488LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302489int encode_set_event_receiver_req(uint8_t instance_id,
2490 uint8_t event_message_global_enable,
2491 uint8_t transport_protocol_type,
2492 uint8_t event_receiver_address_info,
2493 uint16_t heartbeat_timer,
2494 struct pldm_msg *msg)
2495{
2496 if (msg == NULL) {
2497 return PLDM_ERROR_INVALID_DATA;
2498 }
2499
2500 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2501 return PLDM_ERROR_INVALID_DATA;
2502 }
2503
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302504 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302505 header.msg_type = PLDM_REQUEST;
2506 header.instance = instance_id;
2507 header.pldm_type = PLDM_PLATFORM;
2508 header.command = PLDM_SET_EVENT_RECEIVER;
2509
2510 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2511 if (rc != PLDM_SUCCESS) {
2512 return rc;
2513 }
2514
2515 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302516 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302517 request->event_message_global_enable = event_message_global_enable;
2518
2519 request->transport_protocol_type = transport_protocol_type;
2520 request->event_receiver_address_info = event_receiver_address_info;
2521
2522 if (event_message_global_enable ==
2523 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2524 if (heartbeat_timer == 0) {
2525 return PLDM_ERROR_INVALID_DATA;
2526 }
2527 request->heartbeat_timer = htole16(heartbeat_timer);
2528 }
2529
2530 return PLDM_SUCCESS;
2531}
2532
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302533LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302534int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2535 size_t payload_length,
2536 uint8_t *completion_code)
2537{
Andrew Jefferya1896962025-03-03 21:41:25 +10302538 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302539 int rc;
2540
Andrew Jeffery9c766792022-08-10 23:12:49 +09302541 if (msg == NULL || completion_code == NULL) {
2542 return PLDM_ERROR_INVALID_DATA;
2543 }
2544
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302545 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2546 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302547 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302548 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302549 }
2550
Andrew Jeffery66c77232024-04-24 11:42:02 +09302551 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302552
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302553 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302554 if (rc) {
2555 return pldm_xlate_errno(rc);
2556 }
2557
2558 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302559}
2560
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302561LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302562int decode_set_event_receiver_req(const struct pldm_msg *msg,
2563 size_t payload_length,
2564 uint8_t *event_message_global_enable,
2565 uint8_t *transport_protocol_type,
2566 uint8_t *event_receiver_address_info,
2567 uint16_t *heartbeat_timer)
2568
2569{
Andrew Jefferya1896962025-03-03 21:41:25 +10302570 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302571 int rc;
2572
Andrew Jeffery9c766792022-08-10 23:12:49 +09302573 if (msg == NULL || event_message_global_enable == NULL ||
2574 transport_protocol_type == NULL ||
2575 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2576 return PLDM_ERROR_INVALID_DATA;
2577 }
2578
Gilbert Chen98e137d2024-10-08 08:00:39 +00002579 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_MIN_REQ_BYTES,
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302580 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302581 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302582 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302583 }
2584
Andrew Jeffery66c77232024-04-24 11:42:02 +09302585 pldm_msgbuf_extract_p(buf, event_message_global_enable);
Gilbert Chen98e137d2024-10-08 08:00:39 +00002586 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302587 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Gilbert Chen98e137d2024-10-08 08:00:39 +00002588 }
2589
Andrew Jeffery66c77232024-04-24 11:42:02 +09302590 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2591 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
Matt Johnston56ef86a2024-11-12 16:27:19 +08002592 if (*event_message_global_enable ==
2593 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
Gilbert Chen98e137d2024-10-08 08:00:39 +00002594 pldm_msgbuf_extract_p(buf, heartbeat_timer);
2595 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09302596
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302597 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302598 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302599 return pldm_xlate_errno(rc);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302600 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302601
Andrew Jeffery9c766792022-08-10 23:12:49 +09302602 if ((*event_message_global_enable ==
2603 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2604 (*heartbeat_timer == 0)) {
2605 return PLDM_ERROR_INVALID_DATA;
2606 }
2607
Andrew Jeffery9c766792022-08-10 23:12:49 +09302608 return PLDM_SUCCESS;
2609}
2610
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302611LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302612int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2613 struct pldm_msg *msg)
2614
2615{
2616 if (msg == NULL) {
2617 return PLDM_ERROR_INVALID_DATA;
2618 }
2619
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302620 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302621 header.instance = instance_id;
2622 header.msg_type = PLDM_RESPONSE;
2623 header.pldm_type = PLDM_PLATFORM;
2624 header.command = PLDM_SET_EVENT_RECEIVER;
2625
2626 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2627 if (rc != PLDM_SUCCESS) {
2628 return rc;
2629 }
2630
2631 msg->payload[0] = completion_code;
2632
2633 return PLDM_SUCCESS;
2634}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002635
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302636LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002637int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2638 uint8_t format_version,
2639 uint8_t transfer_operation_flag,
2640 uint32_t data_transfer_handle,
2641 uint16_t event_id_to_acknowledge,
2642 struct pldm_msg *msg,
2643 size_t payload_length)
2644{
Andrew Jefferya1896962025-03-03 21:41:25 +10302645 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002646 int rc;
2647
2648 if (msg == NULL) {
2649 return PLDM_ERROR_INVALID_DATA;
2650 }
2651
Thu Nguyen387b10f2024-09-24 11:33:16 +00002652 rc = pldm_platform_poll_for_platform_event_message_validate(
2653 transfer_operation_flag, event_id_to_acknowledge);
2654 if (rc < 0) {
2655 return PLDM_ERROR_INVALID_DATA;
2656 }
2657
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302658 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002659 header.msg_type = PLDM_REQUEST;
2660 header.instance = instance_id;
2661 header.pldm_type = PLDM_PLATFORM;
2662 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2663
2664 rc = pack_pldm_header(&header, &(msg->hdr));
2665 if (rc != PLDM_SUCCESS) {
2666 return rc;
2667 }
2668
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302669 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302670 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2671 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002672 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302673 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002674 }
2675
2676 pldm_msgbuf_insert(buf, format_version);
2677 pldm_msgbuf_insert(buf, transfer_operation_flag);
2678 pldm_msgbuf_insert(buf, data_transfer_handle);
2679 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2680
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302681 rc = pldm_msgbuf_complete(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302682 if (rc) {
2683 return pldm_xlate_errno(rc);
2684 }
2685
2686 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002687}
2688
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302689LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002690int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302691 const struct pldm_msg *msg, size_t payload_length,
2692 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2693 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2694 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2695 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002696{
Andrew Jefferya1896962025-03-03 21:41:25 +10302697 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002698 int rc;
2699
2700 if (msg == NULL || completion_code == NULL || tid == NULL ||
2701 event_id == NULL || next_data_transfer_handle == NULL ||
2702 transfer_flag == NULL || event_class == NULL ||
2703 event_data_size == NULL || event_data == NULL ||
2704 event_data_integrity_checksum == NULL) {
2705 return PLDM_ERROR_INVALID_DATA;
2706 }
2707
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302708 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302709 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2710 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002711 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302712 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002713 }
2714
Andrew Jeffery66c77232024-04-24 11:42:02 +09302715 rc = pldm_msgbuf_extract_p(buf, completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002716 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302717 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002718 }
2719 if (PLDM_SUCCESS != *completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302720 return pldm_msgbuf_discard(buf, *completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002721 }
2722
Andrew Jeffery66c77232024-04-24 11:42:02 +09302723 pldm_msgbuf_extract_p(buf, tid);
2724 rc = pldm_msgbuf_extract_p(buf, event_id);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002725 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302726 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002727 }
2728 if ((*event_id == 0) || (*event_id == 0xffff)) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302729 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002730 }
2731
Andrew Jeffery66c77232024-04-24 11:42:02 +09302732 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2733 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002734 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302735 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002736 }
2737
Andrew Jeffery66c77232024-04-24 11:42:02 +09302738 pldm_msgbuf_extract_p(buf, event_class);
2739 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002740 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302741 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyen159a98b2022-11-02 10:00:10 +07002742 }
2743 if (*event_data_size > payload_length) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302744 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002745 }
2746
2747 if (*event_data_size > 0) {
2748 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2749 }
2750
2751 if (*transfer_flag == PLDM_END ||
2752 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302753 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002754 }
2755
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302756 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302757 if (rc) {
2758 return pldm_xlate_errno(rc);
2759 }
2760
2761 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002762}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002763
2764LIBPLDM_ABI_TESTING
2765int decode_numeric_effecter_pdr_data(
2766 const void *pdr_data, size_t pdr_data_length,
2767 struct pldm_numeric_effecter_value_pdr *pdr_value)
2768{
Andrew Jefferya1896962025-03-03 21:41:25 +10302769 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002770 struct pldm_value_pdr_hdr hdr;
2771 int rc;
2772
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002773 if (!pdr_data || !pdr_value) {
2774 return PLDM_ERROR_INVALID_DATA;
2775 }
2776
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302777 rc = pldm_msgbuf_init_errno(buf,
2778 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2779 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002780 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302781 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002782 }
2783
Andrew Jeffery329176a2024-09-26 22:38:24 +09302784 rc = pldm_msgbuf_extract_value_pdr_hdr(
2785 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
Thu Nguyend4878cd2023-11-09 10:18:33 +07002786 pdr_data_length);
2787 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09302788 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002789 }
2790
2791 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2792
2793 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2794 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2795 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2796 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2797 pldm_msgbuf_extract(buf, pdr_value->container_id);
2798 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2799 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2800 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2801 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2802 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2803 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2804 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2805 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2806 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2807 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2808 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2809 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2810
2811 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2812 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302813 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyend4878cd2023-11-09 10:18:33 +07002814 }
2815 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302816 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002817 }
2818
2819 pldm_msgbuf_extract(buf, pdr_value->resolution);
2820 pldm_msgbuf_extract(buf, pdr_value->offset);
2821 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2822 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2823 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2824 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2825 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2826 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2827 pdr_value->max_settable);
2828 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2829 pdr_value->min_settable);
2830
2831 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2832 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302833 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
Thu Nguyend4878cd2023-11-09 10:18:33 +07002834 }
2835 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302836 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002837 }
2838
2839 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2840 pldm_msgbuf_extract_range_field_format(
2841 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2842 pldm_msgbuf_extract_range_field_format(
2843 buf, pdr_value->range_field_format, pdr_value->normal_max);
2844 pldm_msgbuf_extract_range_field_format(
2845 buf, pdr_value->range_field_format, pdr_value->normal_min);
2846 pldm_msgbuf_extract_range_field_format(
2847 buf, pdr_value->range_field_format, pdr_value->rated_max);
2848 pldm_msgbuf_extract_range_field_format(
2849 buf, pdr_value->range_field_format, pdr_value->rated_min);
2850
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302851 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302852 if (rc) {
2853 return pldm_xlate_errno(rc);
2854 }
2855
2856 return PLDM_SUCCESS;
Thu Nguyend4878cd2023-11-09 10:18:33 +07002857}
Tal Yacobia6fa5552024-05-05 16:57:38 +03002858
Tal Yacobide67ab62024-05-30 22:36:50 +03002859LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002860int encode_get_state_effecter_states_req(uint8_t instance_id,
2861 uint16_t effecter_id,
2862 struct pldm_msg *msg,
2863 size_t payload_length)
2864{
Andrew Jefferya1896962025-03-03 21:41:25 +10302865 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002866 int rc;
2867
2868 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002869 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002870 }
2871
2872 struct pldm_header_info header = { 0 };
2873 header.msg_type = PLDM_REQUEST;
2874 header.instance = instance_id;
2875 header.pldm_type = PLDM_PLATFORM;
2876 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2877
Tal Yacobif490a382024-05-31 09:57:36 +03002878 rc = pack_pldm_header_errno(&header, &msg->hdr);
2879 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002880 return rc;
2881 }
2882
Tal Yacobif490a382024-05-31 09:57:36 +03002883 rc = pldm_msgbuf_init_errno(buf,
2884 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2885 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002886 if (rc) {
2887 return rc;
2888 }
2889
2890 pldm_msgbuf_insert(buf, effecter_id);
2891
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302892 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002893}
2894
Tal Yacobide67ab62024-05-30 22:36:50 +03002895LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002896int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
2897 size_t payload_length,
2898 uint16_t *effecter_id)
2899{
Andrew Jefferya1896962025-03-03 21:41:25 +10302900 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002901 int rc;
2902
2903 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002904 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002905 }
2906
Tal Yacobif490a382024-05-31 09:57:36 +03002907 rc = pldm_msgbuf_init_errno(
2908 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2909 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002910 if (rc) {
2911 return rc;
2912 }
2913
2914 pldm_msgbuf_extract_p(buf, effecter_id);
2915
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302916 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002917}
2918
Tal Yacobide67ab62024-05-30 22:36:50 +03002919LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002920int decode_get_state_effecter_states_resp(
2921 const struct pldm_msg *msg, size_t payload_length,
2922 struct pldm_get_state_effecter_states_resp *resp)
2923{
Andrew Jefferya1896962025-03-03 21:41:25 +10302924 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002925 get_effecter_state_field *field;
2926 int rc;
2927 int i;
2928
2929 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002930 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002931 }
2932
Tal Yacobif490a382024-05-31 09:57:36 +03002933 rc = pldm_msgbuf_init_errno(
2934 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2935 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002936 if (rc) {
2937 return rc;
2938 }
2939
2940 rc = pldm_msgbuf_extract(buf, resp->completion_code);
2941 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302942 return pldm_msgbuf_discard(buf, rc);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002943 }
2944
2945 if (PLDM_SUCCESS != resp->completion_code) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302946 return pldm_msgbuf_complete(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002947 }
2948
2949 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
2950 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302951 return pldm_msgbuf_discard(buf, rc);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002952 }
2953
2954 uint8_t comp_effecter_count = resp->comp_effecter_count;
2955
2956 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2957 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Andrew Jefferya1896962025-03-03 21:41:25 +10302958 return pldm_msgbuf_discard(buf, -EBADMSG);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002959 }
2960
2961 for (i = 0, field = resp->field; i < comp_effecter_count;
2962 i++, field++) {
2963 pldm_msgbuf_extract(buf, field->effecter_op_state);
2964 pldm_msgbuf_extract(buf, field->pending_state);
2965 pldm_msgbuf_extract(buf, field->present_state);
2966 }
2967
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302968 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002969}
2970
Tal Yacobide67ab62024-05-30 22:36:50 +03002971LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002972int encode_get_state_effecter_states_resp(
2973 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
2974 struct pldm_msg *msg, size_t payload_length)
2975{
Andrew Jefferya1896962025-03-03 21:41:25 +10302976 PLDM_MSGBUF_DEFINE_P(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002977 get_effecter_state_field *field;
2978 int rc;
2979 int i;
2980
2981 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002982 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002983 }
2984
2985 uint8_t comp_effecter_count = resp->comp_effecter_count;
2986
2987 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2988 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002989 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002990 }
2991
2992 struct pldm_header_info header = { 0 };
2993 header.msg_type = PLDM_RESPONSE;
2994 header.instance = instance_id;
2995 header.pldm_type = PLDM_PLATFORM;
2996 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2997
Tal Yacobif490a382024-05-31 09:57:36 +03002998 rc = pack_pldm_header_errno(&header, &msg->hdr);
2999 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03003000 return rc;
3001 }
3002
Tal Yacobif490a382024-05-31 09:57:36 +03003003 rc = pldm_msgbuf_init_errno(
3004 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3005 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003006 if (rc) {
3007 return rc;
3008 }
3009
3010 pldm_msgbuf_insert(buf, resp->completion_code);
3011 pldm_msgbuf_insert(buf, comp_effecter_count);
3012
3013 for (i = 0, field = resp->field; i < comp_effecter_count;
3014 i++, field++) {
3015 pldm_msgbuf_insert(buf, field->effecter_op_state);
3016 pldm_msgbuf_insert(buf, field->pending_state);
3017 pldm_msgbuf_insert(buf, field->present_state);
3018 }
3019
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303020 return pldm_msgbuf_complete_consumed(buf);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003021}
Thu Nguyendacfa352024-06-22 09:53:15 +00003022
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003023LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003024int decode_entity_auxiliary_names_pdr(
3025 const void *data, size_t data_length,
3026 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3027{
Andrew Jefferya1896962025-03-03 21:41:25 +10303028 PLDM_MSGBUF_DEFINE_P(buf);
3029 PLDM_MSGBUF_DEFINE_P(src);
3030 PLDM_MSGBUF_DEFINE_P(dst);
Thu Nguyendacfa352024-06-22 09:53:15 +00003031 size_t names_len = 0;
3032 void *names = NULL;
3033 int rc;
3034 int i;
3035
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003036 if (!data || !pdr) {
3037 return -EINVAL;
3038 }
3039
Thu Nguyendacfa352024-06-22 09:53:15 +00003040 /*
3041 * Alignment of auxiliary_name_data is an invariant as we statically assert
3042 * its behaviour in the header.
3043 */
3044 assert(!((uintptr_t)pdr->auxiliary_name_data &
3045 (alignof(pldm_utf16be) - 1)));
3046
3047 /* Reject any lengths that are obviously invalid */
3048 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3049 return -EINVAL;
3050 }
3051
3052 rc = pldm_msgbuf_init_errno(
3053 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3054 data_length);
3055 if (rc) {
3056 return rc;
3057 }
3058
Andrew Jeffery329176a2024-09-26 22:38:24 +09303059 rc = pldm_msgbuf_extract_value_pdr_hdr(
3060 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
Thu Nguyendacfa352024-06-22 09:53:15 +00003061 data_length);
3062 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303063 return pldm_msgbuf_discard(buf, rc);
Thu Nguyendacfa352024-06-22 09:53:15 +00003064 }
3065
3066 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3067 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3068 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3069 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3070 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3071 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303072 return pldm_msgbuf_discard(buf, rc);
Thu Nguyendacfa352024-06-22 09:53:15 +00003073 }
3074
3075 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3076 if (rc < 0) {
3077 return rc;
3078 }
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003079 assert(names);
Thu Nguyendacfa352024-06-22 09:53:15 +00003080
Andrew Jefferya1896962025-03-03 21:41:25 +10303081 rc = pldm_msgbuf_complete_consumed(buf);
3082 if (rc) {
3083 return rc;
3084 }
3085
Thu Nguyendacfa352024-06-22 09:53:15 +00003086 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3087
3088 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3089 pdr->auxiliary_name_data,
3090 pdr->auxiliary_name_data_size);
3091 if (rc < 0) {
3092 return rc;
3093 }
3094
3095 /*
3096 * Below we do two passes over the same region. This is to first pack the
3097 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3098 * to maintain appropriate alignment.
3099 */
3100
3101 /* Initialise for the first pass to extract the UTF16-BE name strings */
3102 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3103 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303104 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003105 }
3106
3107 for (i = 0; i < pdr->name_string_count; i++) {
3108 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003109 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3110 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303111 goto cleanup_msgbuf_src;
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003112 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003113 }
3114
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303115 rc = pldm_msgbuf_complete_consumed(src);
Thu Nguyendacfa352024-06-22 09:53:15 +00003116 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303117 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003118 }
3119
3120 /* Reinitialise for the second pass to extract the ASCII tag strings */
3121 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3122 if (rc < 0) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303123 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003124 }
3125
3126 for (i = 0; i < pdr->name_string_count; i++) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003127 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3128 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303129 goto cleanup_msgbuf_src;
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003130 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003131 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3132 }
3133
Andrew Jefferya1896962025-03-03 21:41:25 +10303134 rc = pldm_msgbuf_complete(src);
3135 if (rc) {
3136 goto cleanup_msgbuf_dst;
Thu Nguyendacfa352024-06-22 09:53:15 +00003137 }
3138
Andrew Jefferya1896962025-03-03 21:41:25 +10303139 return pldm_msgbuf_complete(dst);
3140
3141cleanup_msgbuf_src:
3142 rc = pldm_msgbuf_discard(src, rc);
3143cleanup_msgbuf_dst:
3144 return pldm_msgbuf_discard(dst, rc);
Thu Nguyendacfa352024-06-22 09:53:15 +00003145}
3146
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003147LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003148int decode_pldm_entity_auxiliary_names_pdr_index(
3149 struct pldm_entity_auxiliary_names_pdr *pdr)
3150{
Andrew Jefferya1896962025-03-03 21:41:25 +10303151 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyendacfa352024-06-22 09:53:15 +00003152 int rc;
3153 int i;
3154
3155 if (!pdr) {
3156 return -EINVAL;
3157 }
3158
3159 if (pdr->name_string_count == 0 && pdr->names) {
3160 return -EINVAL;
3161 }
3162
3163 if (pdr->name_string_count > 0 && !pdr->names) {
3164 return -EINVAL;
3165 }
3166
3167 if (pdr->name_string_count == 0) {
3168 return 0;
3169 }
3170
3171 /*
3172 * Minimum size is one NUL for each member of each entry
3173 *
3174 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3175 * states the following:
3176 *
3177 * > A null-terminated ISO646 ASCII string ...
3178 * >
3179 * > special value: null string = 0x0000 = unspecified.
3180 *
3181 * Until proven otherwise we will assume the "0x0000" is a
3182 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3183 * represented by a single byte.
3184 */
3185 rc = pldm_msgbuf_init_errno(
3186 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3187 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3188 if (rc) {
3189 return rc;
3190 }
3191
3192 for (i = 0; i < pdr->name_string_count; i++) {
3193 void *loc = NULL;
3194 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3195 pdr->names[i].name = loc;
3196 }
3197
3198 for (i = 0; i < pdr->name_string_count; i++) {
3199 void *loc = NULL;
3200 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3201 pdr->names[i].tag = loc;
3202 }
3203
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303204 return pldm_msgbuf_complete_consumed(buf);
Thu Nguyendacfa352024-06-22 09:53:15 +00003205}
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003206
Thu Nguyen3559aa12024-08-29 00:13:38 +00003207LIBPLDM_ABI_STABLE
Thu Nguyen02903032024-09-03 06:39:50 +00003208int decode_pldm_platform_cper_event(const void *event_data,
3209 size_t event_data_length,
3210 struct pldm_platform_cper_event *cper_event,
3211 size_t cper_event_length)
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003212{
Andrew Jefferya1896962025-03-03 21:41:25 +10303213 PLDM_MSGBUF_DEFINE_P(buf);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003214 int rc;
3215
3216 if (!cper_event || !event_data) {
3217 return -EINVAL;
3218 }
3219
3220 if (cper_event_length < sizeof(*cper_event)) {
3221 return -EINVAL;
3222 }
3223
3224 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3225 event_data, event_data_length);
3226 if (rc) {
3227 return rc;
3228 }
3229
3230 pldm_msgbuf_extract(buf, cper_event->format_version);
3231 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3232 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303233 return pldm_msgbuf_discard(buf, rc);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003234 }
3235 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3236 cper_event->format_type !=
3237 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303238 return pldm_msgbuf_discard(buf, -EPROTO);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003239 }
3240
3241 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3242 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303243 return pldm_msgbuf_discard(buf, rc);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003244 }
3245
3246 if (cper_event->event_data_length >
3247 (cper_event_length - sizeof(*cper_event))) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303248 return pldm_msgbuf_discard(buf, -EOVERFLOW);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003249 }
3250
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003251 rc = pldm_msgbuf_extract_array_uint8(
3252 buf, cper_event->event_data_length, cper_event->event_data,
3253 cper_event_length - sizeof(*cper_event));
3254 if (rc) {
Andrew Jefferya1896962025-03-03 21:41:25 +10303255 return pldm_msgbuf_discard(buf, rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003256 }
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003257
Andrew Jeffery70d21c92025-03-05 12:59:42 +10303258 return pldm_msgbuf_complete_consumed(buf);
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003259}
3260
Thu Nguyen3559aa12024-08-29 00:13:38 +00003261LIBPLDM_ABI_STABLE
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003262uint8_t *
3263pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3264{
3265 return event->event_data;
3266}
Chau Lyed4ad702025-03-13 04:12:04 +00003267
3268LIBPLDM_ABI_TESTING
3269int decode_pldm_file_descriptor_pdr(const void *data, size_t data_length,
3270 struct pldm_file_descriptor_pdr *pdr)
3271{
3272 PLDM_MSGBUF_DEFINE_P(buf);
3273 int rc;
3274
3275 if (!data || !pdr) {
3276 return -EINVAL;
3277 }
3278
3279 rc = pldm_msgbuf_init_errno(buf,
3280 PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
3281 data, data_length);
3282 if (rc) {
3283 return rc;
3284 }
3285
3286 rc = pldm_msgbuf_extract_value_pdr_hdr(
3287 buf, &pdr->hdr, PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
3288 data_length);
3289 if (rc) {
3290 return pldm_msgbuf_discard(buf, rc);
3291 }
3292
3293 pldm_msgbuf_extract(buf, pdr->terminus_handle);
3294 pldm_msgbuf_extract(buf, pdr->file_identifier);
3295 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3296 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3297 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3298 pldm_msgbuf_extract(buf, pdr->superior_directory_file_identifier);
3299 pldm_msgbuf_extract(buf, pdr->file_classification);
3300 pldm_msgbuf_extract(buf, pdr->oem_file_classification);
3301 pldm_msgbuf_extract(buf, pdr->file_capabilities.value);
3302 pldm_msgbuf_extract(buf, pdr->file_version.alpha);
3303 pldm_msgbuf_extract(buf, pdr->file_version.update);
3304 pldm_msgbuf_extract(buf, pdr->file_version.minor);
3305 pldm_msgbuf_extract(buf, pdr->file_version.major);
3306 pldm_msgbuf_extract(buf, pdr->file_maximum_size);
3307 pldm_msgbuf_extract(buf, pdr->file_maximum_file_descriptor_count);
3308 rc = pldm_msgbuf_extract_uint8_to_size(buf, pdr->file_name.length);
3309 if (rc) {
3310 return pldm_msgbuf_discard(buf, rc);
3311 }
3312
3313 pldm_msgbuf_span_required(buf, pdr->file_name.length,
3314 (void **)&pdr->file_name.ptr);
3315
3316 pdr->oem_file_classification_name.length = 0;
3317
3318 if (pdr->oem_file_classification) {
3319 rc = pldm_msgbuf_extract_uint8_to_size(
3320 buf, pdr->oem_file_classification_name.length);
3321 if (rc) {
3322 return pldm_msgbuf_discard(buf, rc);
3323 }
3324
3325 pldm_msgbuf_span_required(
3326 buf, pdr->oem_file_classification_name.length,
3327 (void **)&pdr->oem_file_classification_name.ptr);
3328 }
3329
3330 return pldm_msgbuf_complete_consumed(buf);
3331}