blob: 5391f61b91a805337cc436e0b8a1055351ab2739 [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{
25 // Encode possible states
26
27 size_t calculated_possible_states_size = 0;
28
29 {
30 char *states_ptr = (char *)possible_states;
31 char *const begin_states_ptr = states_ptr;
32
33 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
34 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093035 (struct state_effecter_possible_states *)
36 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093037
38 HTOLE16(states->state_set_id);
39
40 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093041 (sizeof(*states) - sizeof(states->states) +
42 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093043 }
44
45 calculated_possible_states_size = states_ptr - begin_states_ptr;
46 }
47
48 // Check lengths
49
50 if (possible_states_size != calculated_possible_states_size) {
51 *actual_size = 0;
52 return PLDM_ERROR;
53 }
54
55 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093056 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
57 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093058
59 if (allocation_size < *actual_size) {
60 *actual_size = 0;
61 return PLDM_ERROR_INVALID_LENGTH;
62 }
63
64 // Encode rest of PDR
65
66 effecter->hdr.version = 1;
67 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
68 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
69
70 memcpy(effecter->possible_states, possible_states,
71 possible_states_size);
72
73 // Convert effecter PDR body
74 HTOLE16(effecter->terminus_handle);
75 HTOLE16(effecter->effecter_id);
76 HTOLE16(effecter->entity_type);
77 HTOLE16(effecter->entity_instance);
78 HTOLE16(effecter->container_id);
79 HTOLE16(effecter->effecter_semantic_id);
80
81 // Convert header
82 HTOLE32(effecter->hdr.record_handle);
83 HTOLE16(effecter->hdr.record_change_num);
84 HTOLE16(effecter->hdr.length);
85
86 return PLDM_SUCCESS;
87}
88
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093089LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093090int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093091 struct pldm_state_sensor_pdr *const sensor,
92 const size_t allocation_size,
93 const struct state_sensor_possible_states *const possible_states,
94 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093095{
Andrew Jeffery9c766792022-08-10 23:12:49 +093096 size_t calculated_possible_states_size = 0;
97
Andrew Jefferybb50a592024-09-26 21:59:44 +093098 if (!sensor || !possible_states || !actual_size) {
99 return PLDM_ERROR;
100 }
101
102 if (SIZE_MAX - (sizeof(*sensor) - sizeof(sensor->possible_states)) <
103 possible_states_size) {
104 return PLDM_ERROR;
105 }
106
107 if (allocation_size <
108 (sizeof(*sensor) - sizeof(sensor->possible_states) +
109 possible_states_size)) {
110 return PLDM_ERROR_INVALID_LENGTH;
111 }
112
Andrew Jeffery9c766792022-08-10 23:12:49 +0930113 {
Andrew Jefferybb50a592024-09-26 21:59:44 +0930114 // Encode possible states
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930115 char *states_ptr = (char *)possible_states;
116 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930117
118 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
119 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930120 (struct state_sensor_possible_states *)
121 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930122
123 HTOLE16(states->state_set_id);
124
125 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930126 (sizeof(*states) - sizeof(states->states) +
127 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930128 }
129
130 calculated_possible_states_size = states_ptr - begin_states_ptr;
131 }
132
133 // Check lengths
134
135 if (possible_states_size != calculated_possible_states_size) {
136 *actual_size = 0;
137 return PLDM_ERROR;
138 }
139
140 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
141 possible_states_size - sizeof(sensor->possible_states));
142
Andrew Jeffery9c766792022-08-10 23:12:49 +0930143 // Encode rest of PDR
144
145 sensor->hdr.version = 1;
146 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
147 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
148
149 memcpy(sensor->possible_states, possible_states, possible_states_size);
150
151 // Convert sensor PDR body
152 HTOLE16(sensor->terminus_handle);
153 HTOLE16(sensor->sensor_id);
154 HTOLE16(sensor->entity_type);
155 HTOLE16(sensor->entity_instance);
156 HTOLE16(sensor->container_id);
157
158 // Convert header
159 HTOLE32(sensor->hdr.record_handle);
160 HTOLE16(sensor->hdr.record_change_num);
161 HTOLE16(sensor->hdr.length);
162
163 return PLDM_SUCCESS;
164}
165
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930166LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930167int encode_set_state_effecter_states_resp(uint8_t instance_id,
168 uint8_t completion_code,
169 struct pldm_msg *msg)
170{
171 if (msg == NULL) {
172 return PLDM_ERROR_INVALID_DATA;
173 }
174
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930175 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930176 header.msg_type = PLDM_RESPONSE;
177 header.instance = instance_id;
178 header.pldm_type = PLDM_PLATFORM;
179 header.command = PLDM_SET_STATE_EFFECTER_STATES;
180
181 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
182 if (rc != PLDM_SUCCESS) {
183 return rc;
184 }
185
186 msg->payload[0] = completion_code;
187
188 return PLDM_SUCCESS;
189}
190
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930191LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930192int encode_set_state_effecter_states_req(uint8_t instance_id,
193 uint16_t effecter_id,
194 uint8_t comp_effecter_count,
195 set_effecter_state_field *field,
196 struct pldm_msg *msg)
197{
198 if (msg == NULL) {
199 return PLDM_ERROR_INVALID_DATA;
200 }
201
202 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
203 field == NULL) {
204 return PLDM_ERROR_INVALID_DATA;
205 }
206
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930207 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930208 header.msg_type = PLDM_REQUEST;
209 header.instance = instance_id;
210 header.pldm_type = PLDM_PLATFORM;
211 header.command = PLDM_SET_STATE_EFFECTER_STATES;
212
213 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
214 if (rc != PLDM_SUCCESS) {
215 return rc;
216 }
217
218 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930219 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930220 effecter_id = htole16(effecter_id);
221 request->effecter_id = effecter_id;
222 request->comp_effecter_count = comp_effecter_count;
223 memcpy(request->field, field,
224 (sizeof(set_effecter_state_field) * comp_effecter_count));
225
226 return PLDM_SUCCESS;
227}
228
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930229LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930230int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
231 size_t payload_length,
232 uint8_t *completion_code)
233{
234 if (msg == NULL || completion_code == NULL) {
235 return PLDM_ERROR_INVALID_DATA;
236 }
237
238 *completion_code = msg->payload[0];
239 if (PLDM_SUCCESS != *completion_code) {
240 return PLDM_SUCCESS;
241 }
242
243 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
244 return PLDM_ERROR_INVALID_LENGTH;
245 }
246
247 return PLDM_SUCCESS;
248}
249
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930250#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930251LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930252int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
253 size_t payload_length,
254 uint16_t *effecter_id,
255 uint8_t *comp_effecter_count,
256 set_effecter_state_field *field)
257{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930258 struct pldm_msgbuf _buf;
259 struct pldm_msgbuf *buf = &_buf;
260 int rc;
261 int i;
262
Andrew Jeffery9c766792022-08-10 23:12:49 +0930263 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
264 field == NULL) {
265 return PLDM_ERROR_INVALID_DATA;
266 }
267
268 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
269 return PLDM_ERROR_INVALID_LENGTH;
270 }
271
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930272 rc = pldm_msgbuf_init_errno(buf,
273 PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
274 msg->payload, payload_length);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930275 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930276 return pldm_xlate_errno(rc);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930277 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930278
Andrew Jeffery66c77232024-04-24 11:42:02 +0930279 pldm_msgbuf_extract_p(buf, effecter_id);
280 pldm_msgbuf_extract_p(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930281
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930282 if (*comp_effecter_count > 8) {
283 return PLDM_ERROR_INVALID_DATA;
284 }
285
286 for (i = 0; i < *comp_effecter_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930287 pldm_msgbuf_extract(buf, field[i].set_request);
288 pldm_msgbuf_extract(buf, field[i].effecter_state);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930289 }
290
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930291 rc = pldm_msgbuf_destroy(buf);
292 if (rc) {
293 return pldm_xlate_errno(rc);
294 }
295
296 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930297}
298
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930299LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930300int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
301 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
302 uint8_t *transfer_op_flag, uint16_t *request_cnt,
303 uint16_t *record_chg_num)
304{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930305 struct pldm_msgbuf _buf;
306 struct pldm_msgbuf *buf = &_buf;
307 int rc;
308
Andrew Jeffery9c766792022-08-10 23:12:49 +0930309 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
310 transfer_op_flag == NULL || request_cnt == NULL ||
311 record_chg_num == NULL) {
312 return PLDM_ERROR_INVALID_DATA;
313 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930314
Andrew Jeffery9c766792022-08-10 23:12:49 +0930315 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
316 return PLDM_ERROR_INVALID_LENGTH;
317 }
318
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930319 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
320 payload_length);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930321 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930322 return pldm_xlate_errno(rc);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930323 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930324
Andrew Jeffery66c77232024-04-24 11:42:02 +0930325 pldm_msgbuf_extract_p(buf, record_hndl);
326 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
327 pldm_msgbuf_extract_p(buf, transfer_op_flag);
328 pldm_msgbuf_extract_p(buf, request_cnt);
329 pldm_msgbuf_extract_p(buf, record_chg_num);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930330
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930331 rc = pldm_msgbuf_destroy(buf);
332 if (rc) {
333 return pldm_xlate_errno(rc);
334 }
335
336 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930337}
338
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930339LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930340int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
341 uint32_t next_record_hndl,
342 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
343 uint16_t resp_cnt, const uint8_t *record_data,
344 uint8_t transfer_crc, struct pldm_msg *msg)
345{
346 if (msg == NULL) {
347 return PLDM_ERROR_INVALID_DATA;
348 }
349
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930350 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930351 header.msg_type = PLDM_RESPONSE;
352 header.instance = instance_id;
353 header.pldm_type = PLDM_PLATFORM;
354 header.command = PLDM_GET_PDR;
355
356 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
357 if (rc != PLDM_SUCCESS) {
358 return rc;
359 }
360
361 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930362 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930363 response->completion_code = completion_code;
364
365 if (response->completion_code == PLDM_SUCCESS) {
366 response->next_record_handle = htole32(next_record_hndl);
367 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930368 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930369 response->transfer_flag = transfer_flag;
370 response->response_count = htole16(resp_cnt);
371 if (record_data != NULL && resp_cnt > 0) {
372 memcpy(response->record_data, record_data, resp_cnt);
373 }
374 if (transfer_flag == PLDM_END) {
375 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930376 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
377 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930378 *dst = transfer_crc;
379 }
380 }
381
382 return PLDM_SUCCESS;
383}
384
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930385LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930386int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930387 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
388 const uint8_t *update_time, const uint8_t *oem_update_time,
389 uint32_t record_count, uint32_t repository_size,
390 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
391 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930392{
393 if (msg == NULL) {
394 return PLDM_ERROR_INVALID_DATA;
395 }
396
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930397 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930398 header.msg_type = PLDM_RESPONSE;
399 header.instance = instance_id;
400 header.pldm_type = PLDM_PLATFORM;
401 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
402
403 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
404 if (rc != PLDM_SUCCESS) {
405 return rc;
406 }
407
408 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930409 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930410 response->completion_code = completion_code;
411
412 if (response->completion_code == PLDM_SUCCESS) {
413 response->repository_state = repository_state;
414 if (update_time != NULL) {
415 memcpy(response->update_time, update_time,
416 PLDM_TIMESTAMP104_SIZE);
417 }
418 if (oem_update_time != NULL) {
419 memcpy(response->oem_update_time, oem_update_time,
420 PLDM_TIMESTAMP104_SIZE);
421 }
422 response->record_count = htole32(record_count);
423 response->repository_size = htole32(repository_size);
424 response->largest_record_size = htole32(largest_record_size);
425 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930426 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930427 }
428
429 return PLDM_SUCCESS;
430}
431
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000432LIBPLDM_ABI_DEPRECATED
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800433int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930434 const struct pldm_msg *msg, size_t payload_length,
435 uint8_t *completion_code, uint8_t *repository_state,
436 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
437 uint32_t *repository_size, uint32_t *largest_record_size,
438 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800439{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930440 struct pldm_msgbuf _buf;
441 struct pldm_msgbuf *buf = &_buf;
442 int rc;
443
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800444 if (msg == NULL || completion_code == NULL ||
445 repository_state == NULL || update_time == NULL ||
446 oem_update_time == NULL || record_count == NULL ||
447 repository_size == NULL || largest_record_size == NULL ||
448 data_transfer_handle_timeout == NULL) {
449 return PLDM_ERROR_INVALID_DATA;
450 }
451
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930452 rc = pldm_msgbuf_init_errno(buf,
453 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
454 msg->payload, payload_length);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930455 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930456 return pldm_xlate_errno(rc);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930457 }
458
Andrew Jeffery66c77232024-04-24 11:42:02 +0930459 pldm_msgbuf_extract_p(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800460 if (PLDM_SUCCESS != *completion_code) {
461 return PLDM_SUCCESS;
462 }
463
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930464 rc = pldm_msgbuf_extract_p(buf, repository_state);
465 if (rc) {
466 return pldm_xlate_errno(rc);
467 }
468
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800469 if (*repository_state > PLDM_FAILED) {
470 return PLDM_ERROR_INVALID_DATA;
471 }
472
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000473 /* NOTE: Memory safety */
474 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
475 PLDM_TIMESTAMP104_SIZE);
476 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930477 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000478 }
479
480 /* NOTE: Memory safety */
481 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
482 oem_update_time, PLDM_TIMESTAMP104_SIZE);
483 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930484 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000485 }
486
Andrew Jeffery66c77232024-04-24 11:42:02 +0930487 pldm_msgbuf_extract_p(buf, record_count);
488 pldm_msgbuf_extract_p(buf, repository_size);
489 pldm_msgbuf_extract_p(buf, largest_record_size);
490 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800491
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930492 rc = pldm_msgbuf_destroy(buf);
493 if (rc) {
494 return pldm_xlate_errno(rc);
495 }
496
497 return PLDM_SUCCESS;
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800498}
499
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000500LIBPLDM_ABI_TESTING
501int decode_get_pdr_repository_info_resp_safe(
502 const struct pldm_msg *msg, size_t payload_length,
503 struct pldm_pdr_repository_info_resp *resp)
504{
505 struct pldm_msgbuf _buf;
506 struct pldm_msgbuf *buf = &_buf;
507 int rc;
508
509 if (msg == NULL || resp == NULL) {
510 return -EINVAL;
511 }
512
513 rc = pldm_msg_has_error(msg, payload_length);
514 if (rc) {
515 resp->completion_code = rc;
516 return 0;
517 }
518
519 rc = pldm_msgbuf_init_errno(buf,
520 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
521 msg->payload, payload_length);
522 if (rc) {
523 return rc;
524 }
525
526 rc = pldm_msgbuf_extract(buf, resp->completion_code);
527 if (rc) {
528 return rc;
529 }
530
531 pldm_msgbuf_extract(buf, resp->repository_state);
532
533 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
534 resp->update_time,
535 sizeof(resp->update_time));
536 if (rc) {
537 return rc;
538 }
539
540 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
541 resp->oem_update_time,
542 sizeof(resp->oem_update_time));
543 if (rc) {
544 return rc;
545 }
546
547 pldm_msgbuf_extract(buf, resp->record_count);
548 pldm_msgbuf_extract(buf, resp->repository_size);
549 pldm_msgbuf_extract(buf, resp->largest_record_size);
550 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
551
552 return pldm_msgbuf_destroy_consumed(buf);
553}
554
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930555LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930556int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
557 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
558 uint16_t request_cnt, uint16_t record_chg_num,
559 struct pldm_msg *msg, size_t payload_length)
560{
561 if (msg == NULL) {
562 return PLDM_ERROR_INVALID_DATA;
563 }
564
565 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
566 return PLDM_ERROR_INVALID_LENGTH;
567 }
568
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930569 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930570 header.msg_type = PLDM_REQUEST;
571 header.instance = instance_id;
572 header.pldm_type = PLDM_PLATFORM;
573 header.command = PLDM_GET_PDR;
574
575 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
576 if (rc != PLDM_SUCCESS) {
577 return rc;
578 }
579
580 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930581 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930582 request->record_handle = htole32(record_hndl);
583 request->data_transfer_handle = htole32(data_transfer_hndl);
584 request->transfer_op_flag = transfer_op_flag;
585 request->request_count = htole16(request_cnt);
586 request->record_change_number = htole16(record_chg_num);
587
588 return PLDM_SUCCESS;
589}
590
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000591LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930592int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
593 uint8_t *completion_code, uint32_t *next_record_hndl,
594 uint32_t *next_data_transfer_hndl,
595 uint8_t *transfer_flag, uint16_t *resp_cnt,
596 uint8_t *record_data, size_t record_data_length,
597 uint8_t *transfer_crc)
598{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930599 struct pldm_msgbuf _buf;
600 struct pldm_msgbuf *buf = &_buf;
601 int rc;
602
Andrew Jeffery9c766792022-08-10 23:12:49 +0930603 if (msg == NULL || completion_code == NULL ||
604 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
605 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
606 return PLDM_ERROR_INVALID_DATA;
607 }
608
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930609 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
610 msg->payload, payload_length);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930611 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930612 return pldm_xlate_errno(rc);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930613 }
614
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930615 rc = pldm_msgbuf_extract_p(buf, completion_code);
616 if (rc) {
617 return pldm_xlate_errno(rc);
618 }
619
Andrew Jeffery9c766792022-08-10 23:12:49 +0930620 if (PLDM_SUCCESS != *completion_code) {
621 return PLDM_SUCCESS;
622 }
623
Andrew Jeffery66c77232024-04-24 11:42:02 +0930624 pldm_msgbuf_extract_p(buf, next_record_hndl);
625 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
626 pldm_msgbuf_extract_p(buf, transfer_flag);
627 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930628 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930629 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930630 }
631
632 if (*resp_cnt > 0 && record_data != NULL) {
633 if (record_data_length < *resp_cnt) {
634 return PLDM_ERROR_INVALID_LENGTH;
635 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000636 /* NOTE: Memory safety */
637 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
638 *resp_cnt);
639 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930640 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000641 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930642 }
643
644 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930645 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930646 }
647
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930648 rc = pldm_msgbuf_destroy(buf);
649 if (rc) {
650 return pldm_xlate_errno(rc);
651 }
652
653 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930654}
655
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000656LIBPLDM_ABI_TESTING
657int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
658 struct pldm_get_pdr_resp *resp, size_t resp_len,
659 uint8_t *transfer_crc)
660{
661 struct pldm_msgbuf _buf;
662 struct pldm_msgbuf *buf = &_buf;
663 int rc;
664
665 if (msg == NULL || resp == NULL || transfer_crc == NULL) {
666 return -EINVAL;
667 }
668
669 rc = pldm_msg_has_error(msg, payload_length);
670 if (rc) {
671 resp->completion_code = rc;
672 return 0;
673 }
674
675 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
676 msg->payload, payload_length);
677 if (rc) {
678 return rc;
679 }
680
681 pldm_msgbuf_extract(buf, resp->completion_code);
682 pldm_msgbuf_extract(buf, resp->next_record_handle);
683 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
684
685 rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
686 if (rc) {
687 return rc;
688 }
689
690 rc = pldm_msgbuf_extract(buf, resp->response_count);
691 if (rc) {
692 return rc;
693 }
694
695 rc = pldm_msgbuf_extract_array(
696 buf, resp->response_count, resp->record_data,
697 resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
698 if (rc) {
699 return rc;
700 }
701
702 if (resp->transfer_flag == PLDM_END) {
703 pldm_msgbuf_extract_p(buf, transfer_crc);
704 }
705
706 return pldm_msgbuf_destroy_consumed(buf);
707}
708
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930709LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930710int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
711 size_t payload_length,
712 uint16_t *effecter_id,
713 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930714 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930715{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930716 struct pldm_msgbuf _buf;
717 struct pldm_msgbuf *buf = &_buf;
718 int rc;
719
Andrew Jeffery9c766792022-08-10 23:12:49 +0930720 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
721 effecter_value == NULL) {
722 return PLDM_ERROR_INVALID_DATA;
723 }
724
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930725 rc = pldm_msgbuf_init_errno(
726 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
727 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930728 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930729 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930730 }
731
Andrew Jeffery66c77232024-04-24 11:42:02 +0930732 pldm_msgbuf_extract_p(buf, effecter_id);
733 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930734 if (rc) {
735 return PLDM_ERROR_INVALID_DATA;
736 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930737
738 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
739 return PLDM_ERROR_INVALID_DATA;
740 }
741
Andrew Jeffery3884c442023-04-12 11:13:24 +0930742 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
743 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930744
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930745 rc = pldm_msgbuf_destroy(buf);
746 if (rc) {
747 return pldm_xlate_errno(rc);
748 }
749
750 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930751}
752
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930753LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930754int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
755 uint8_t completion_code,
756 struct pldm_msg *msg,
757 size_t payload_length)
758{
759 if (msg == NULL) {
760 return PLDM_ERROR_INVALID_DATA;
761 }
762
763 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
764 return PLDM_ERROR_INVALID_LENGTH;
765 }
766
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930767 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930768 header.msg_type = PLDM_RESPONSE;
769 header.instance = instance_id;
770 header.pldm_type = PLDM_PLATFORM;
771 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
772
773 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
774 if (rc != PLDM_SUCCESS) {
775 return rc;
776 }
777
778 msg->payload[0] = completion_code;
779
780 return rc;
781}
782
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930783LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930784int encode_set_numeric_effecter_value_req(uint8_t instance_id,
785 uint16_t effecter_id,
786 uint8_t effecter_data_size,
787 const uint8_t *effecter_value,
788 struct pldm_msg *msg,
789 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930790{
791 if (msg == NULL || effecter_value == NULL) {
792 return PLDM_ERROR_INVALID_DATA;
793 }
794
795 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
796 return PLDM_ERROR_INVALID_DATA;
797 }
798
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930799 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930800 header.msg_type = PLDM_REQUEST;
801 header.instance = instance_id;
802 header.pldm_type = PLDM_PLATFORM;
803 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
804
805 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
806 if (rc != PLDM_SUCCESS) {
807 return rc;
808 }
809
810 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930811 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930812 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
813 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
814 if (payload_length !=
815 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
816 return PLDM_ERROR_INVALID_LENGTH;
817 }
818 request->effecter_value[0] = *effecter_value;
819 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
820 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
821 if (payload_length !=
822 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
823 return PLDM_ERROR_INVALID_LENGTH;
824 }
825
826 uint16_t val = *(uint16_t *)(effecter_value);
827 val = htole16(val);
828 memcpy(request->effecter_value, &val, sizeof(uint16_t));
829
830 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
831 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
832 if (payload_length !=
833 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
834 return PLDM_ERROR_INVALID_LENGTH;
835 }
836
837 uint32_t val = *(uint32_t *)(effecter_value);
838 val = htole32(val);
839 memcpy(request->effecter_value, &val, sizeof(uint32_t));
840 }
841
842 request->effecter_id = htole16(effecter_id);
843 request->effecter_data_size = effecter_data_size;
844
845 return PLDM_SUCCESS;
846}
847
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930848LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930849int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
850 size_t payload_length,
851 uint8_t *completion_code)
852{
853 if (msg == NULL || completion_code == NULL) {
854 return PLDM_ERROR_INVALID_DATA;
855 }
856
857 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
858 return PLDM_ERROR_INVALID_LENGTH;
859 }
860
861 *completion_code = msg->payload[0];
862
863 return PLDM_SUCCESS;
864}
865
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930866LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930867int encode_get_state_sensor_readings_resp(uint8_t instance_id,
868 uint8_t completion_code,
869 uint8_t comp_sensor_count,
870 get_sensor_state_field *field,
871 struct pldm_msg *msg)
872{
873 if (msg == NULL) {
874 return PLDM_ERROR_INVALID_DATA;
875 }
876
877 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
878 return PLDM_ERROR_INVALID_DATA;
879 }
880
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930881 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930882 header.msg_type = PLDM_RESPONSE;
883 header.instance = instance_id;
884 header.pldm_type = PLDM_PLATFORM;
885 header.command = PLDM_GET_STATE_SENSOR_READINGS;
886
887 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
888 if (rc != PLDM_SUCCESS) {
889 return rc;
890 }
891
892 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930893 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930894
895 response->completion_code = completion_code;
896 response->comp_sensor_count = comp_sensor_count;
897 memcpy(response->field, field,
898 (sizeof(get_sensor_state_field) * comp_sensor_count));
899
900 return PLDM_SUCCESS;
901}
902
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930903LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930904int encode_get_state_sensor_readings_req(uint8_t instance_id,
905 uint16_t sensor_id,
906 bitfield8_t sensor_rearm,
907 uint8_t reserved, struct pldm_msg *msg)
908{
909 if (msg == NULL) {
910 return PLDM_ERROR_INVALID_DATA;
911 }
912
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930913 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930914 header.msg_type = PLDM_REQUEST;
915 header.instance = instance_id;
916 header.pldm_type = PLDM_PLATFORM;
917 header.command = PLDM_GET_STATE_SENSOR_READINGS;
918
919 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
920 if (rc != PLDM_SUCCESS) {
921 return rc;
922 }
923
924 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930925 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930926
927 request->sensor_id = htole16(sensor_id);
928 request->reserved = reserved;
929 request->sensor_rearm = sensor_rearm;
930
931 return PLDM_SUCCESS;
932}
933
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930934LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930935int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
936 size_t payload_length,
937 uint8_t *completion_code,
938 uint8_t *comp_sensor_count,
939 get_sensor_state_field *field)
940{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930941 struct pldm_msgbuf _buf;
942 struct pldm_msgbuf *buf = &_buf;
943 uint8_t i;
944 int rc;
945
Andrew Jeffery9c766792022-08-10 23:12:49 +0930946 if (msg == NULL || completion_code == NULL ||
947 comp_sensor_count == NULL || field == NULL) {
948 return PLDM_ERROR_INVALID_DATA;
949 }
950
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930951 rc = pldm_msgbuf_init_errno(
952 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
953 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930954 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930955 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930956 }
957
Andrew Jeffery66c77232024-04-24 11:42:02 +0930958 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930959 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930960 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930961 }
962
Andrew Jeffery9c766792022-08-10 23:12:49 +0930963 if (PLDM_SUCCESS != *completion_code) {
964 return PLDM_SUCCESS;
965 }
966
Andrew Jeffery66c77232024-04-24 11:42:02 +0930967 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930968 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930969 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930970 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930971
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930972 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930973 return PLDM_ERROR_INVALID_DATA;
974 }
975
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930976 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930977 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
978 pldm_msgbuf_extract(buf, field[i].present_state);
979 pldm_msgbuf_extract(buf, field[i].previous_state);
980 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930981 }
982
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930983 rc = pldm_msgbuf_destroy_consumed(buf);
984 if (rc) {
985 return pldm_xlate_errno(rc);
986 }
987
988 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930989}
990
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930991LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930992int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
993 size_t payload_length,
994 uint16_t *sensor_id,
995 bitfield8_t *sensor_rearm,
996 uint8_t *reserved)
997{
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930998 struct pldm_msgbuf _buf;
999 struct pldm_msgbuf *buf = &_buf;
1000 int rc;
1001
Andrew Jeffery9c766792022-08-10 23:12:49 +09301002 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
1003 return PLDM_ERROR_INVALID_DATA;
1004 }
1005
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301006 rc = pldm_msgbuf_init_errno(buf,
1007 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
1008 msg->payload, payload_length);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301009 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301010 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301011 }
1012
Andrew Jeffery66c77232024-04-24 11:42:02 +09301013 pldm_msgbuf_extract_p(buf, sensor_id);
1014 pldm_msgbuf_extract(buf, sensor_rearm->byte);
1015 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301016
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301017 rc = pldm_msgbuf_destroy(buf);
1018 if (rc) {
1019 return pldm_xlate_errno(rc);
1020 }
1021
1022 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301023}
1024
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301025LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301026int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301027 struct pldm_sensor_event_data *const event_data,
1028 const size_t event_data_size, const uint16_t sensor_id,
1029 const enum sensor_event_class_states sensor_event_class,
1030 const uint8_t sensor_offset, const uint8_t event_state,
1031 const uint8_t previous_event_state,
1032 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301033{
1034 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301035 (sizeof(*event_data) - sizeof(event_data->event_class) +
1036 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301037
1038 if (!event_data) {
1039 return PLDM_SUCCESS;
1040 }
1041
1042 if (event_data_size < *actual_event_data_size) {
1043 *actual_event_data_size = 0;
1044 return PLDM_ERROR_INVALID_LENGTH;
1045 }
1046
1047 event_data->sensor_id = htole16(sensor_id);
1048 event_data->sensor_event_class_type = sensor_event_class;
1049
1050 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301051 (struct pldm_sensor_event_state_sensor_state *)
1052 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301053
1054 state_data->sensor_offset = sensor_offset;
1055 state_data->event_state = event_state;
1056 state_data->previous_event_state = previous_event_state;
1057
1058 return PLDM_SUCCESS;
1059}
1060
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301061LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301062int decode_platform_event_message_req(const struct pldm_msg *msg,
1063 size_t payload_length,
1064 uint8_t *format_version, uint8_t *tid,
1065 uint8_t *event_class,
1066 size_t *event_data_offset)
1067{
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301068 struct pldm_msgbuf _buf;
1069 struct pldm_msgbuf *buf = &_buf;
1070 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301071
1072 if (msg == NULL || format_version == NULL || tid == NULL ||
1073 event_class == NULL || event_data_offset == NULL) {
1074 return PLDM_ERROR_INVALID_DATA;
1075 }
1076
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301077 rc = pldm_msgbuf_init_errno(buf,
1078 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
1079 msg->payload, payload_length);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301080 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301081 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301082 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301083
Andrew Jeffery66c77232024-04-24 11:42:02 +09301084 pldm_msgbuf_extract_p(buf, format_version);
1085 pldm_msgbuf_extract_p(buf, tid);
1086 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301087
1088 rc = pldm_msgbuf_destroy(buf);
1089 if (rc) {
1090 return pldm_xlate_errno(rc);
1091 }
1092
Andrew Jeffery9c766792022-08-10 23:12:49 +09301093 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301094 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301095
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301096 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301097}
1098
Thu Nguyen387b10f2024-09-24 11:33:16 +00001099static int pldm_platform_poll_for_platform_event_message_validate(
1100 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1101{
1102 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1103 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1104 ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1105 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1106 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
Thu Nguyen9e16b182024-10-01 03:12:16 +00001107 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1108 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1109 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
Thu Nguyen387b10f2024-09-24 11:33:16 +00001110 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1111 return -EPROTO;
1112 }
1113
1114 return 0;
1115}
1116
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301117LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001118int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301119 const struct pldm_msg *msg, size_t payload_length,
1120 uint8_t *format_version, uint8_t *transfer_operation_flag,
1121 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001122{
1123 struct pldm_msgbuf _buf;
1124 struct pldm_msgbuf *buf = &_buf;
1125 int rc;
1126
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001127 if (msg == NULL || format_version == NULL ||
1128 transfer_operation_flag == NULL || data_transfer_handle == NULL ||
1129 event_id_to_acknowledge == NULL) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001130 return PLDM_ERROR_INVALID_DATA;
1131 }
1132
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301133 rc = pldm_msgbuf_init_errno(
1134 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
1135 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001136 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301137 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001138 }
1139
Andrew Jeffery66c77232024-04-24 11:42:02 +09301140 pldm_msgbuf_extract_p(buf, format_version);
1141 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
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 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
1146 return PLDM_ERROR_INVALID_DATA;
1147 }
1148
Andrew Jeffery66c77232024-04-24 11:42:02 +09301149 pldm_msgbuf_extract_p(buf, data_transfer_handle);
1150 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001151 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301152 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001153 }
1154
Thu Nguyen387b10f2024-09-24 11:33:16 +00001155 rc = pldm_platform_poll_for_platform_event_message_validate(
1156 *transfer_operation_flag, *event_id_to_acknowledge);
1157 if (rc < 0) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001158 return PLDM_ERROR_INVALID_DATA;
1159 }
1160
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301161 rc = pldm_msgbuf_destroy(buf);
1162 if (rc) {
1163 return pldm_xlate_errno(rc);
1164 }
1165
1166 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001167}
1168
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301169LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301170int encode_platform_event_message_resp(uint8_t instance_id,
1171 uint8_t completion_code,
1172 uint8_t platform_event_status,
1173 struct pldm_msg *msg)
1174{
1175 if (msg == NULL) {
1176 return PLDM_ERROR_INVALID_DATA;
1177 }
1178
1179 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1180 return PLDM_ERROR_INVALID_DATA;
1181 }
1182
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301183 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301184 header.msg_type = PLDM_RESPONSE;
1185 header.instance = instance_id;
1186 header.pldm_type = PLDM_PLATFORM;
1187 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1188
1189 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1190 if (rc != PLDM_SUCCESS) {
1191 return rc;
1192 }
1193
1194 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301195 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301196 response->completion_code = completion_code;
1197 response->platform_event_status = platform_event_status;
1198
1199 return PLDM_SUCCESS;
1200}
1201
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301202LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001203int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301204 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1205 uint16_t event_id, uint32_t next_data_transfer_handle,
1206 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1207 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1208 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001209{
1210 struct pldm_msgbuf _buf;
1211 struct pldm_msgbuf *buf = &_buf;
1212 int rc;
1213
1214 if (!msg) {
1215 return PLDM_ERROR_INVALID_DATA;
1216 }
1217
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301218 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001219 header.msg_type = PLDM_RESPONSE;
1220 header.instance = instance_id;
1221 header.pldm_type = PLDM_PLATFORM;
1222 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1223
1224 rc = pack_pldm_header(&header, &(msg->hdr));
1225 if (rc != PLDM_SUCCESS) {
1226 return rc;
1227 }
1228
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301229 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301230 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1231 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001232 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301233 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001234 }
1235
1236 pldm_msgbuf_insert(buf, completion_code);
1237 pldm_msgbuf_insert(buf, tid);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301238 rc = pldm_msgbuf_insert(buf, event_id);
1239 if (rc) {
1240 return pldm_xlate_errno(rc);
1241 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001242
1243 if (event_id == 0xffff || event_id == 0x0000) {
1244 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1245 payload_length) {
1246 return PLDM_ERROR_INVALID_LENGTH;
1247 }
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301248
1249 rc = pldm_msgbuf_destroy(buf);
1250 if (rc) {
1251 return pldm_xlate_errno(rc);
1252 }
1253
1254 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001255 }
1256
1257 if ((event_data == NULL) && (event_data_size > 0)) {
1258 return PLDM_ERROR_INVALID_DATA;
1259 }
1260
1261 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1262 pldm_msgbuf_insert(buf, transfer_flag);
1263 pldm_msgbuf_insert(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301264 rc = pldm_msgbuf_insert(buf, event_data_size);
1265 if (rc) {
1266 return pldm_xlate_errno(rc);
1267 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001268
1269 if ((event_data_size > 0) && event_data) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001270 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
1271 event_data_size);
1272 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301273 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001274 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001275 }
1276
1277 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1278 pldm_msgbuf_insert(buf, checksum);
1279 }
1280
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301281 rc = pldm_msgbuf_destroy(buf);
1282 if (rc) {
1283 return pldm_xlate_errno(rc);
1284 }
1285
1286 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001287}
1288
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301289LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301290int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301291 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1292 uint8_t event_class, const uint8_t *event_data,
1293 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301294
1295{
1296 if (format_version != 1) {
1297 return PLDM_ERROR_INVALID_DATA;
1298 }
1299
1300 if (msg == NULL || event_data == NULL) {
1301 return PLDM_ERROR_INVALID_DATA;
1302 }
1303
1304 if (event_data_length == 0) {
1305 return PLDM_ERROR_INVALID_DATA;
1306 }
1307
Andrew Jeffery225530a2024-09-25 13:11:43 +09301308 if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1309 event_data_length) {
1310 return PLDM_ERROR_INVALID_LENGTH;
1311 }
1312
Andrew Jeffery9c766792022-08-10 23:12:49 +09301313 if (payload_length !=
1314 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1315 return PLDM_ERROR_INVALID_LENGTH;
1316 }
1317
John Chungb43a7782024-09-26 22:04:27 +08001318 if (event_class > PLDM_CPER_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001319 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301320 return PLDM_ERROR_INVALID_DATA;
1321 }
1322
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301323 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301324 header.msg_type = PLDM_REQUEST;
1325 header.instance = instance_id;
1326 header.pldm_type = PLDM_PLATFORM;
1327 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1328
1329 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1330 if (rc != PLDM_SUCCESS) {
1331 return rc;
1332 }
1333
1334 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301335 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301336 request->format_version = format_version;
1337 request->tid = tid;
1338 request->event_class = event_class;
1339 memcpy(request->event_data, event_data, event_data_length);
1340
1341 return PLDM_SUCCESS;
1342}
1343
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301344LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301345int decode_platform_event_message_resp(const struct pldm_msg *msg,
1346 size_t payload_length,
1347 uint8_t *completion_code,
1348 uint8_t *platform_event_status)
1349{
Andrew Jefferye5011772023-04-13 12:06:22 +09301350 struct pldm_msgbuf _buf;
1351 struct pldm_msgbuf *buf = &_buf;
1352 int rc;
1353
Andrew Jeffery9c766792022-08-10 23:12:49 +09301354 if (msg == NULL || completion_code == NULL ||
1355 platform_event_status == NULL) {
1356 return PLDM_ERROR_INVALID_DATA;
1357 }
1358
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301359 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1360 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301361 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301362 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301363 }
1364
Andrew Jeffery66c77232024-04-24 11:42:02 +09301365 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301366 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301367 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301368 }
1369
Andrew Jeffery9c766792022-08-10 23:12:49 +09301370 if (PLDM_SUCCESS != *completion_code) {
1371 return PLDM_SUCCESS;
1372 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301373
Andrew Jeffery66c77232024-04-24 11:42:02 +09301374 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301375 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301376 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301377 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301378
1379 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1380 return PLDM_ERROR_INVALID_DATA;
1381 }
1382
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301383 rc = pldm_msgbuf_destroy(buf);
1384 if (rc) {
1385 return pldm_xlate_errno(rc);
1386 }
1387
1388 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301389}
1390
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301391LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301392int encode_event_message_buffer_size_req(uint8_t instance_id,
1393 uint16_t event_receiver_max_buffer_size,
1394 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001395{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301396 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001397 header.msg_type = PLDM_REQUEST;
1398 header.instance = instance_id;
1399 header.pldm_type = PLDM_PLATFORM;
1400 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1401
1402 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1403 if (rc != PLDM_SUCCESS) {
1404 return rc;
1405 }
1406
1407 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301408 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001409 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301410 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001411
1412 return PLDM_SUCCESS;
1413}
1414
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301415LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001416int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1417 size_t payload_length,
1418 uint8_t *completion_code,
1419 uint16_t *terminus_max_buffer_size)
1420{
Andrew Jeffery11126902023-04-13 12:12:10 +09301421 struct pldm_msgbuf _buf;
1422 struct pldm_msgbuf *buf = &_buf;
1423 int rc;
1424
Dung Caod6ae8982022-11-02 10:00:10 +07001425 if (msg == NULL || completion_code == NULL ||
1426 terminus_max_buffer_size == NULL) {
1427 return PLDM_ERROR_INVALID_DATA;
1428 }
1429
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301430 rc = pldm_msgbuf_init_errno(buf,
1431 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1432 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301433 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301434 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301435 }
1436
Andrew Jeffery66c77232024-04-24 11:42:02 +09301437 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301438 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301439 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301440 }
1441
Dung Caod6ae8982022-11-02 10:00:10 +07001442 if (PLDM_SUCCESS != *completion_code) {
1443 return PLDM_SUCCESS;
1444 }
Dung Caod6ae8982022-11-02 10:00:10 +07001445
Andrew Jeffery66c77232024-04-24 11:42:02 +09301446 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001447
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301448 rc = pldm_msgbuf_destroy_consumed(buf);
1449 if (rc) {
1450 return pldm_xlate_errno(rc);
1451 }
1452
1453 return PLDM_SUCCESS;
Dung Caod6ae8982022-11-02 10:00:10 +07001454}
1455
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301456LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001457int encode_event_message_supported_req(uint8_t instance_id,
1458 uint8_t format_version,
1459 struct pldm_msg *msg)
1460{
1461 if (format_version != 1) {
1462 return PLDM_ERROR_INVALID_DATA;
1463 }
1464
1465 if (msg == NULL) {
1466 return PLDM_ERROR_INVALID_DATA;
1467 }
1468
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301469 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001470 header.msg_type = PLDM_REQUEST;
1471 header.instance = instance_id;
1472 header.pldm_type = PLDM_PLATFORM;
1473 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1474
1475 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1476 if (rc != PLDM_SUCCESS) {
1477 return rc;
1478 }
1479
1480 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301481 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001482 request->format_version = format_version;
1483
1484 return PLDM_SUCCESS;
1485}
1486
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301487LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301488int decode_event_message_supported_resp(const struct pldm_msg *msg,
1489 size_t payload_length,
1490 uint8_t *completion_code,
1491 uint8_t *synchrony_config,
1492 bitfield8_t *synchrony_config_support,
1493 uint8_t *number_event_class_returned,
1494 uint8_t *event_class,
1495 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001496{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301497 struct pldm_msgbuf _buf;
1498 struct pldm_msgbuf *buf = &_buf;
1499 int i;
1500 int rc;
1501
Dung Cao1bf8c872022-11-29 05:32:58 +07001502 if (msg == NULL || completion_code == NULL ||
1503 synchrony_config == NULL || synchrony_config_support == NULL ||
1504 number_event_class_returned == NULL || event_class == NULL) {
1505 return PLDM_ERROR_INVALID_DATA;
1506 }
1507
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301508 rc = pldm_msgbuf_init_errno(buf,
1509 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1510 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301511 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301512 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301513 }
1514
Andrew Jeffery66c77232024-04-24 11:42:02 +09301515 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301516 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301517 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301518 }
1519
Dung Cao1bf8c872022-11-29 05:32:58 +07001520 if (PLDM_SUCCESS != *completion_code) {
1521 return PLDM_SUCCESS;
1522 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301523
Andrew Jeffery66c77232024-04-24 11:42:02 +09301524 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301525 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301526 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001527 }
1528
Dung Cao1bf8c872022-11-29 05:32:58 +07001529 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1530 return PLDM_ERROR_INVALID_DATA;
1531 }
1532
Andrew Jeffery66c77232024-04-24 11:42:02 +09301533 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001534
Andrew Jeffery66c77232024-04-24 11:42:02 +09301535 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301536 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301537 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001538 }
1539
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301540 if (*number_event_class_returned == 0) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301541 rc = pldm_msgbuf_destroy(buf);
1542 if (rc) {
1543 return pldm_xlate_errno(rc);
1544 }
1545
1546 return PLDM_SUCCESS;
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301547 }
1548
1549 if (event_class_count < *number_event_class_returned) {
1550 return PLDM_ERROR_INVALID_LENGTH;
1551 }
1552
1553 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301554 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301555 }
1556
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301557 rc = pldm_msgbuf_destroy_consumed(buf);
1558 if (rc) {
1559 return pldm_xlate_errno(rc);
1560 }
1561
1562 return PLDM_SUCCESS;
Dung Cao1bf8c872022-11-29 05:32:58 +07001563}
1564
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301565LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301566int decode_sensor_event_data(const uint8_t *event_data,
1567 size_t event_data_length, uint16_t *sensor_id,
1568 uint8_t *sensor_event_class_type,
1569 size_t *event_class_data_offset)
1570{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301571 struct pldm_msgbuf _buf;
1572 struct pldm_msgbuf *buf = &_buf;
1573 int rc;
1574
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001575 if (event_data == NULL || sensor_id == NULL ||
1576 sensor_event_class_type == NULL ||
1577 event_class_data_offset == NULL) {
1578 return PLDM_ERROR_INVALID_DATA;
1579 }
1580
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301581 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1582 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301583 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301584 return pldm_xlate_errno(rc);
1585 }
1586
1587 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1588 return PLDM_ERROR_INVALID_LENGTH;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301589 }
1590
1591 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301592 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301593
Andrew Jeffery66c77232024-04-24 11:42:02 +09301594 pldm_msgbuf_extract_p(buf, sensor_id);
1595 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301596 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301597 return pldm_xlate_errno(rc);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301598 }
1599
1600 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301601 if (event_class_data_length !=
1602 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1603 return PLDM_ERROR_INVALID_LENGTH;
1604 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301605 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301606 if (event_class_data_length !=
1607 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1608 return PLDM_ERROR_INVALID_LENGTH;
1609 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301610 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301611 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301612 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301613 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301614 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301615 return PLDM_ERROR_INVALID_LENGTH;
1616 }
1617 } else {
1618 return PLDM_ERROR_INVALID_DATA;
1619 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301620
Andrew Jeffery9c766792022-08-10 23:12:49 +09301621 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301622 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301623
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301624 rc = pldm_msgbuf_destroy(buf);
1625 if (rc) {
1626 return pldm_xlate_errno(rc);
1627 }
1628
1629 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301630}
1631
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301632LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301633int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1634 uint8_t *present_op_state, uint8_t *previous_op_state)
1635{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301636 struct pldm_msgbuf _buf;
1637 struct pldm_msgbuf *buf = &_buf;
1638 int rc;
1639
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001640 if (sensor_data == NULL || present_op_state == NULL ||
1641 previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301642 return PLDM_ERROR_INVALID_DATA;
1643 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301644
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301645 rc = pldm_msgbuf_init_errno(
1646 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1647 sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301648 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301649 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301650 }
1651
Andrew Jeffery66c77232024-04-24 11:42:02 +09301652 pldm_msgbuf_extract_p(buf, present_op_state);
1653 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301654
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301655 rc = pldm_msgbuf_destroy_consumed(buf);
1656 if (rc) {
1657 return pldm_xlate_errno(rc);
1658 }
1659
1660 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301661}
1662
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301663LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301664int decode_state_sensor_data(const uint8_t *sensor_data,
1665 size_t sensor_data_length, uint8_t *sensor_offset,
1666 uint8_t *event_state,
1667 uint8_t *previous_event_state)
1668{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301669 struct pldm_msgbuf _buf;
1670 struct pldm_msgbuf *buf = &_buf;
1671 int rc;
1672
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001673 if (sensor_data == NULL || sensor_offset == NULL ||
1674 event_state == NULL || previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301675 return PLDM_ERROR_INVALID_DATA;
1676 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301677
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301678 rc = pldm_msgbuf_init_errno(
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301679 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1680 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301681 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301682 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301683 }
1684
Andrew Jeffery66c77232024-04-24 11:42:02 +09301685 pldm_msgbuf_extract_p(buf, sensor_offset);
1686 pldm_msgbuf_extract_p(buf, event_state);
1687 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301688
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301689 rc = pldm_msgbuf_destroy_consumed(buf);
1690 if (rc) {
1691 return pldm_xlate_errno(rc);
1692 }
1693
1694 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301695}
1696
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301697LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301698int decode_numeric_sensor_data(const uint8_t *sensor_data,
1699 size_t sensor_data_length, uint8_t *event_state,
1700 uint8_t *previous_event_state,
1701 uint8_t *sensor_data_size,
1702 uint32_t *present_reading)
1703{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301704 struct pldm_msgbuf _buf;
1705 struct pldm_msgbuf *buf = &_buf;
1706 int rc;
1707
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001708 if (sensor_data == NULL || sensor_data_size == NULL ||
1709 event_state == NULL || previous_event_state == NULL ||
1710 present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301711 return PLDM_ERROR_INVALID_DATA;
1712 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301713
1714 if (sensor_data_length >
1715 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301716 return PLDM_ERROR_INVALID_LENGTH;
1717 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301718
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301719 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301720 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1721 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301722 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301723 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301724 }
1725
Andrew Jeffery66c77232024-04-24 11:42:02 +09301726 pldm_msgbuf_extract_p(buf, event_state);
1727 pldm_msgbuf_extract_p(buf, previous_event_state);
1728 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301729 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301730 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301731 }
1732
1733 /*
1734 * The implementation below is bonkers, but it's because the function
1735 * prototype is bonkers. The `present_reading` argument should have been
1736 * a tagged union.
1737 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301738 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301739 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1740 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301741 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301742 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301743 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301744 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301745 }
1746 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1747 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301748 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301749 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301750 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301751 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301752 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301753 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301754 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301755 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301756 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301757 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301758 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301759 }
1760 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301761 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301762 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301763 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301764 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301765 break;
1766 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301767 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1768 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301769 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301770 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301771 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301772 break;
1773 }
1774 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1775 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301776 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301777 *present_reading = (uint32_t)val;
1778 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301779 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301780 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301781 default:
1782 return PLDM_ERROR_INVALID_DATA;
1783 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301784
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301785 rc = pldm_msgbuf_destroy_consumed(buf);
1786 if (rc) {
1787 return pldm_xlate_errno(rc);
1788 }
1789
1790 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301791}
1792
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301793LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301794int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301795 const void *pdr_data, size_t pdr_data_length,
1796 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301797{
1798 struct pldm_msgbuf _buf;
1799 struct pldm_msgbuf *buf = &_buf;
1800 int rc;
1801
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301802 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1803 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301804 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301805 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301806 }
1807
Andrew Jeffery329176a2024-09-26 22:38:24 +09301808 rc = pldm_msgbuf_extract_value_pdr_hdr(
1809 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301810 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301811 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09301812 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301813 }
1814
Andrew Jeffery66c77232024-04-24 11:42:02 +09301815 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1816 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1817 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1818 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1819 pldm_msgbuf_extract(buf, pdr_value->container_id);
1820 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1821 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1822 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1823 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1824 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1825 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1826 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1827 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1828 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1829 pldm_msgbuf_extract(buf, pdr_value->rel);
1830 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1831 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301832
Andrew Jeffery66c77232024-04-24 11:42:02 +09301833 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301834 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301835 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301836 }
1837 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1838 return PLDM_ERROR_INVALID_DATA;
1839 }
1840
Andrew Jeffery66c77232024-04-24 11:42:02 +09301841 pldm_msgbuf_extract(buf, pdr_value->resolution);
1842 pldm_msgbuf_extract(buf, pdr_value->offset);
1843 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1844 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1845 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301846 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1847 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301848 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301849 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301850 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1851 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1852 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301853 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1854 &pdr_value->max_readable);
1855 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1856 &pdr_value->min_readable);
1857
Andrew Jeffery66c77232024-04-24 11:42:02 +09301858 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301859 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301860 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301861 }
1862 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1863 return PLDM_ERROR_INVALID_DATA;
1864 }
1865
Andrew Jeffery66c77232024-04-24 11:42:02 +09301866 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301867 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301868 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301869 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301870 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301871 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301872 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301873 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301874 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301875 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301876 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301877 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301878 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301879 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301880 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301881 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301882 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301883 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301884 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301885
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301886 rc = pldm_msgbuf_destroy(buf);
1887 if (rc) {
1888 return pldm_xlate_errno(rc);
1889 }
1890
1891 return PLDM_SUCCESS;
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301892}
1893
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301894LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301895int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1896 uint16_t effecter_id,
1897 struct pldm_msg *msg)
1898{
1899 if (msg == NULL) {
1900 return PLDM_ERROR_INVALID_DATA;
1901 }
1902
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301903 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301904 header.msg_type = PLDM_REQUEST;
1905 header.instance = instance_id;
1906 header.pldm_type = PLDM_PLATFORM;
1907 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1908
1909 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1910 if (rc != PLDM_SUCCESS) {
1911 return rc;
1912 }
1913
1914 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301915 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301916 request->effecter_id = htole16(effecter_id);
1917
1918 return PLDM_SUCCESS;
1919}
1920
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301921LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301922int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301923 uint8_t instance_id, uint8_t completion_code,
1924 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1925 const uint8_t *pending_value, const uint8_t *present_value,
1926 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301927{
1928 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1929 return PLDM_ERROR_INVALID_DATA;
1930 }
1931
1932 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1933 return PLDM_ERROR_INVALID_DATA;
1934 }
1935
1936 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1937 return PLDM_ERROR_INVALID_DATA;
1938 }
1939
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301940 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301941 header.msg_type = PLDM_RESPONSE;
1942 header.instance = instance_id;
1943 header.pldm_type = PLDM_PLATFORM;
1944 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1945
1946 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1947 if (rc != PLDM_SUCCESS) {
1948 return rc;
1949 }
1950
1951 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301952 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301953
1954 response->completion_code = completion_code;
1955 response->effecter_data_size = effecter_data_size;
1956 response->effecter_oper_state = effecter_oper_state;
1957
1958 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1959 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1960 if (payload_length !=
1961 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1962 return PLDM_ERROR_INVALID_LENGTH;
1963 }
1964 response->pending_and_present_values[0] = *pending_value;
1965 response->pending_and_present_values[1] = *present_value;
1966
1967 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1968 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1969 if (payload_length !=
1970 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1971 return PLDM_ERROR_INVALID_LENGTH;
1972 }
1973 uint16_t val_pending = *(uint16_t *)pending_value;
1974 val_pending = htole16(val_pending);
1975 memcpy(response->pending_and_present_values, &val_pending,
1976 sizeof(uint16_t));
1977 uint16_t val_present = *(uint16_t *)present_value;
1978 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301979 memcpy((response->pending_and_present_values +
1980 sizeof(uint16_t)),
1981 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301982
1983 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1984 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1985 if (payload_length !=
1986 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1987 return PLDM_ERROR_INVALID_LENGTH;
1988 }
1989 uint32_t val_pending = *(uint32_t *)pending_value;
1990 val_pending = htole32(val_pending);
1991 memcpy(response->pending_and_present_values, &val_pending,
1992 sizeof(uint32_t));
1993 uint32_t val_present = *(uint32_t *)present_value;
1994 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301995 memcpy((response->pending_and_present_values +
1996 sizeof(uint32_t)),
1997 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301998 }
1999 return PLDM_SUCCESS;
2000}
2001
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302002LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302003int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
2004 size_t payload_length,
2005 uint16_t *effecter_id)
2006{
Andrew Jefferydd265822023-04-13 22:42:44 +09302007 struct pldm_msgbuf _buf;
2008 struct pldm_msgbuf *buf = &_buf;
2009 int rc;
2010
Andrew Jeffery9c766792022-08-10 23:12:49 +09302011 if (msg == NULL || effecter_id == NULL) {
2012 return PLDM_ERROR_INVALID_DATA;
2013 }
2014
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302015 rc = pldm_msgbuf_init_errno(buf,
2016 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2017 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09302018 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302019 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302020 }
2021
Andrew Jeffery66c77232024-04-24 11:42:02 +09302022 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302023
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302024 rc = pldm_msgbuf_destroy_consumed(buf);
2025 if (rc) {
2026 return pldm_xlate_errno(rc);
2027 }
2028
2029 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302030}
2031
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302032LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302033int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2034 size_t payload_length,
2035 uint8_t *completion_code,
2036 uint8_t *effecter_data_size,
2037 uint8_t *effecter_oper_state,
2038 uint8_t *pending_value,
2039 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302040{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302041 struct pldm_msgbuf _buf;
2042 struct pldm_msgbuf *buf = &_buf;
2043 int rc;
2044
Andrew Jeffery9c766792022-08-10 23:12:49 +09302045 if (msg == NULL || effecter_data_size == NULL ||
2046 effecter_oper_state == NULL || pending_value == NULL ||
2047 present_value == NULL) {
2048 return PLDM_ERROR_INVALID_DATA;
2049 }
2050
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302051 rc = pldm_msgbuf_init_errno(
2052 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2053 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302054 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302055 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302056 }
2057
Andrew Jeffery66c77232024-04-24 11:42:02 +09302058 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302059 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302060 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302061 }
2062
Andrew Jeffery9c766792022-08-10 23:12:49 +09302063 if (PLDM_SUCCESS != *completion_code) {
2064 return PLDM_SUCCESS;
2065 }
2066
Andrew Jeffery66c77232024-04-24 11:42:02 +09302067 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302068 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302069 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302070 }
2071
Andrew Jeffery9c766792022-08-10 23:12:49 +09302072 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2073 return PLDM_ERROR_INVALID_DATA;
2074 }
2075
Andrew Jeffery66c77232024-04-24 11:42:02 +09302076 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302077 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302078 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302079 }
2080
Andrew Jeffery9c766792022-08-10 23:12:49 +09302081 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
2082 return PLDM_ERROR_INVALID_DATA;
2083 }
2084
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302085 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2086 pending_value);
2087 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2088 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302089
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302090 rc = pldm_msgbuf_destroy_consumed(buf);
2091 if (rc) {
2092 return pldm_xlate_errno(rc);
2093 }
2094
2095 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302096}
2097
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302098LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302099int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302100 uint8_t event_data_format, uint8_t number_of_change_records,
2101 const uint8_t *event_data_operations,
2102 const uint8_t *numbers_of_change_entries,
2103 const uint32_t *const *change_entries,
2104 struct pldm_pdr_repository_chg_event_data *event_data,
2105 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302106{
2107 if (event_data_operations == NULL ||
2108 numbers_of_change_entries == NULL || change_entries == NULL) {
2109 return PLDM_ERROR_INVALID_DATA;
2110 }
2111
2112 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302113 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302114
2115 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302116 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302117 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302118 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302119
2120 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302121 expected_size += sizeof(*change_entries[0]) *
2122 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302123 }
2124
2125 *actual_change_records_size = expected_size;
2126
2127 if (event_data == NULL) {
2128 return PLDM_SUCCESS;
2129 }
2130
2131 if (max_change_records_size < expected_size) {
2132 return PLDM_ERROR_INVALID_LENGTH;
2133 }
2134
2135 event_data->event_data_format = event_data_format;
2136 event_data->number_of_change_records = number_of_change_records;
2137
2138 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302139 (struct pldm_pdr_repository_change_record_data *)
2140 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302141
2142 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2143 record_data->event_data_operation = event_data_operations[i];
2144 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302145 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302146
2147 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2148 ++j) {
2149 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302150 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302151 }
2152
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302153 record_data =
2154 (struct pldm_pdr_repository_change_record_data
2155 *)(record_data->change_entry +
2156 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302157 }
2158
2159 return PLDM_SUCCESS;
2160}
2161
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302162LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302163int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2164 size_t event_data_size,
2165 uint8_t *event_data_format,
2166 uint8_t *number_of_change_records,
2167 size_t *change_record_data_offset)
2168{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302169 struct pldm_msgbuf _buf;
2170 struct pldm_msgbuf *buf = &_buf;
2171 int rc;
2172
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002173 if (event_data == NULL || event_data_format == NULL ||
2174 number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302175 change_record_data_offset == NULL) {
2176 return PLDM_ERROR_INVALID_DATA;
2177 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302178
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302179 rc = pldm_msgbuf_init_errno(buf,
2180 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2181 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302182 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302183 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302184 }
2185
Andrew Jeffery66c77232024-04-24 11:42:02 +09302186 pldm_msgbuf_extract_p(buf, event_data_format);
2187 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302188
Andrew Jeffery9c766792022-08-10 23:12:49 +09302189 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302190 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302191
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302192 rc = pldm_msgbuf_destroy(buf);
2193 if (rc) {
2194 return pldm_xlate_errno(rc);
2195 }
2196
2197 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302198}
2199
Thu Nguyenf874b382024-07-24 11:22:34 +00002200LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00002201int decode_pldm_message_poll_event_data(
2202 const void *event_data, size_t event_data_length,
2203 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07002204{
2205 struct pldm_msgbuf _buf;
2206 struct pldm_msgbuf *buf = &_buf;
2207 int rc;
2208
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002209 if (!event_data || !poll_event) {
Thu Nguyen7739d122024-07-26 11:36:39 +00002210 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07002211 }
2212
Thu Nguyen7739d122024-07-26 11:36:39 +00002213 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2214 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002215 if (rc) {
2216 return rc;
2217 }
2218
Thu Nguyen7739d122024-07-26 11:36:39 +00002219 pldm_msgbuf_extract(buf, poll_event->format_version);
2220 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07002221 if (rc) {
2222 return rc;
2223 }
2224
Thu Nguyen7739d122024-07-26 11:36:39 +00002225 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2226 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002227 }
2228
Thu Nguyen7739d122024-07-26 11:36:39 +00002229 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002230
2231 return pldm_msgbuf_destroy_consumed(buf);
2232}
2233
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302234LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00002235int encode_pldm_message_poll_event_data(
2236 const struct pldm_message_poll_event *poll_event, void *event_data,
2237 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07002238{
2239 struct pldm_msgbuf _buf;
2240 struct pldm_msgbuf *buf = &_buf;
2241 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
Thu Nguyen7739d122024-07-26 11:36:39 +00002260 return pldm_msgbuf_destroy_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 Jeffery61cab6f2023-04-13 23:28:48 +09302269 struct pldm_msgbuf _buf;
2270 struct pldm_msgbuf *buf = &_buf;
2271 int rc;
2272
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002273 if (change_record_data == NULL || event_data_operation == NULL ||
2274 number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302275 change_entry_data_offset == NULL) {
2276 return PLDM_ERROR_INVALID_DATA;
2277 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302278
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302279 rc = pldm_msgbuf_init_errno(
2280 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2281 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302282 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302283 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302284 }
2285
Andrew Jeffery66c77232024-04-24 11:42:02 +09302286 pldm_msgbuf_extract_p(buf, event_data_operation);
2287 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302288
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302289 *change_entry_data_offset = sizeof(*event_data_operation) +
2290 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302291
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302292 rc = pldm_msgbuf_destroy(buf);
2293 if (rc) {
2294 return pldm_xlate_errno(rc);
2295 }
2296
2297 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302298}
2299
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302300LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302301int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2302 uint8_t rearm_event_state,
2303 struct pldm_msg *msg)
2304{
2305 if (msg == NULL) {
2306 return PLDM_ERROR_INVALID_DATA;
2307 }
2308
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302309 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302310 header.msg_type = PLDM_REQUEST;
2311 header.instance = instance_id;
2312 header.pldm_type = PLDM_PLATFORM;
2313 header.command = PLDM_GET_SENSOR_READING;
2314
2315 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2316 if (rc != PLDM_SUCCESS) {
2317 return rc;
2318 }
2319
2320 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302321 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302322
2323 request->sensor_id = htole16(sensor_id);
2324 request->rearm_event_state = rearm_event_state;
2325
2326 return PLDM_SUCCESS;
2327}
2328
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302329LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302330int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302331 const struct pldm_msg *msg, size_t payload_length,
2332 uint8_t *completion_code, uint8_t *sensor_data_size,
2333 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2334 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2335 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302336{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302337 struct pldm_msgbuf _buf;
2338 struct pldm_msgbuf *buf = &_buf;
2339 int rc;
2340
Andrew Jeffery9c766792022-08-10 23:12:49 +09302341 if (msg == NULL || completion_code == NULL ||
2342 sensor_data_size == NULL || sensor_operational_state == NULL ||
2343 sensor_event_message_enable == NULL || present_state == NULL ||
2344 previous_state == NULL || event_state == NULL ||
2345 present_reading == NULL) {
2346 return PLDM_ERROR_INVALID_DATA;
2347 }
2348
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302349 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2350 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302351 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302352 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302353 }
2354
Andrew Jeffery66c77232024-04-24 11:42:02 +09302355 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302356 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302357 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302358 }
2359
Andrew Jeffery9c766792022-08-10 23:12:49 +09302360 if (PLDM_SUCCESS != *completion_code) {
2361 return PLDM_SUCCESS;
2362 }
2363
Andrew Jeffery66c77232024-04-24 11:42:02 +09302364 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302365 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302366 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302367 }
2368
Andrew Jeffery840b1402023-04-13 23:54:44 +09302369 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302370 return PLDM_ERROR_INVALID_DATA;
2371 }
2372
Andrew Jeffery66c77232024-04-24 11:42:02 +09302373 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2374 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2375 pldm_msgbuf_extract_p(buf, present_state);
2376 pldm_msgbuf_extract_p(buf, previous_state);
2377 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302378
Andrew Jeffery840b1402023-04-13 23:54:44 +09302379 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2380 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302381
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302382 rc = pldm_msgbuf_destroy_consumed(buf);
2383 if (rc) {
2384 return pldm_xlate_errno(rc);
2385 }
2386
2387 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302388}
2389
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302390LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302391int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2392 uint8_t sensor_data_size,
2393 uint8_t sensor_operational_state,
2394 uint8_t sensor_event_message_enable,
2395 uint8_t present_state,
2396 uint8_t previous_state, uint8_t event_state,
2397 const uint8_t *present_reading,
2398 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302399{
2400 if (msg == NULL || present_reading == NULL) {
2401 return PLDM_ERROR_INVALID_DATA;
2402 }
2403
2404 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2405 return PLDM_ERROR_INVALID_DATA;
2406 }
2407
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302408 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302409 header.msg_type = PLDM_RESPONSE;
2410 header.instance = instance_id;
2411 header.pldm_type = PLDM_PLATFORM;
2412 header.command = PLDM_GET_SENSOR_READING;
2413
2414 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2415 if (rc != PLDM_SUCCESS) {
2416 return rc;
2417 }
2418
2419 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302420 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302421
2422 response->completion_code = completion_code;
2423 response->sensor_data_size = sensor_data_size;
2424 response->sensor_operational_state = sensor_operational_state;
2425 response->sensor_event_message_enable = sensor_event_message_enable;
2426 response->present_state = present_state;
2427 response->previous_state = previous_state;
2428 response->event_state = event_state;
2429
2430 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2431 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2432 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2433 return PLDM_ERROR_INVALID_LENGTH;
2434 }
2435 response->present_reading[0] = *present_reading;
2436
2437 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2438 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2439 if (payload_length !=
2440 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2441 return PLDM_ERROR_INVALID_LENGTH;
2442 }
2443 uint16_t val = *(uint16_t *)present_reading;
2444 val = htole16(val);
2445 memcpy(response->present_reading, &val, 2);
2446
2447 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2448 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2449 if (payload_length !=
2450 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2451 return PLDM_ERROR_INVALID_LENGTH;
2452 }
2453 uint32_t val = *(uint32_t *)present_reading;
2454 val = htole32(val);
2455 memcpy(response->present_reading, &val, 4);
2456 }
2457
2458 return PLDM_SUCCESS;
2459}
2460
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302461LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302462int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2463 size_t payload_length, uint16_t *sensor_id,
2464 uint8_t *rearm_event_state)
2465{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302466 struct pldm_msgbuf _buf;
2467 struct pldm_msgbuf *buf = &_buf;
2468 int rc;
2469
Andrew Jeffery9c766792022-08-10 23:12:49 +09302470 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2471 return PLDM_ERROR_INVALID_DATA;
2472 }
2473
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302474 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2475 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302476 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302477 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302478 }
2479
Andrew Jeffery66c77232024-04-24 11:42:02 +09302480 pldm_msgbuf_extract_p(buf, sensor_id);
2481 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302482
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302483 rc = pldm_msgbuf_destroy(buf);
2484 if (rc) {
2485 return pldm_xlate_errno(rc);
2486 }
2487
2488 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302489}
2490
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302491LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302492int encode_set_event_receiver_req(uint8_t instance_id,
2493 uint8_t event_message_global_enable,
2494 uint8_t transport_protocol_type,
2495 uint8_t event_receiver_address_info,
2496 uint16_t heartbeat_timer,
2497 struct pldm_msg *msg)
2498{
2499 if (msg == NULL) {
2500 return PLDM_ERROR_INVALID_DATA;
2501 }
2502
2503 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2504 return PLDM_ERROR_INVALID_DATA;
2505 }
2506
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302507 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302508 header.msg_type = PLDM_REQUEST;
2509 header.instance = instance_id;
2510 header.pldm_type = PLDM_PLATFORM;
2511 header.command = PLDM_SET_EVENT_RECEIVER;
2512
2513 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2514 if (rc != PLDM_SUCCESS) {
2515 return rc;
2516 }
2517
2518 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302519 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302520 request->event_message_global_enable = event_message_global_enable;
2521
2522 request->transport_protocol_type = transport_protocol_type;
2523 request->event_receiver_address_info = event_receiver_address_info;
2524
2525 if (event_message_global_enable ==
2526 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2527 if (heartbeat_timer == 0) {
2528 return PLDM_ERROR_INVALID_DATA;
2529 }
2530 request->heartbeat_timer = htole16(heartbeat_timer);
2531 }
2532
2533 return PLDM_SUCCESS;
2534}
2535
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302536LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302537int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2538 size_t payload_length,
2539 uint8_t *completion_code)
2540{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302541 struct pldm_msgbuf _buf;
2542 struct pldm_msgbuf *buf = &_buf;
2543 int rc;
2544
Andrew Jeffery9c766792022-08-10 23:12:49 +09302545 if (msg == NULL || completion_code == NULL) {
2546 return PLDM_ERROR_INVALID_DATA;
2547 }
2548
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302549 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2550 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302551 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302552 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302553 }
2554
Andrew Jeffery66c77232024-04-24 11:42:02 +09302555 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302556
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302557 rc = pldm_msgbuf_destroy(buf);
2558 if (rc) {
2559 return pldm_xlate_errno(rc);
2560 }
2561
2562 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302563}
2564
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302565LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302566int decode_set_event_receiver_req(const struct pldm_msg *msg,
2567 size_t payload_length,
2568 uint8_t *event_message_global_enable,
2569 uint8_t *transport_protocol_type,
2570 uint8_t *event_receiver_address_info,
2571 uint16_t *heartbeat_timer)
2572
2573{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302574 struct pldm_msgbuf _buf;
2575 struct pldm_msgbuf *buf = &_buf;
2576 int rc;
2577
Andrew Jeffery9c766792022-08-10 23:12:49 +09302578 if (msg == NULL || event_message_global_enable == NULL ||
2579 transport_protocol_type == NULL ||
2580 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2581 return PLDM_ERROR_INVALID_DATA;
2582 }
2583
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302584 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2585 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302586 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302587 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302588 }
2589
Andrew Jeffery66c77232024-04-24 11:42:02 +09302590 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2591 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2592 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
Andrew Jeffery2332e052024-10-08 13:52:34 +10302593 pldm_msgbuf_extract_p(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302594
Andrew Jeffery9667f582023-04-14 00:39:21 +09302595 rc = pldm_msgbuf_destroy(buf);
2596 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302597 return pldm_xlate_errno(rc);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302598 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302599
Andrew Jeffery9c766792022-08-10 23:12:49 +09302600 if ((*event_message_global_enable ==
2601 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2602 (*heartbeat_timer == 0)) {
2603 return PLDM_ERROR_INVALID_DATA;
2604 }
2605
Andrew Jeffery9c766792022-08-10 23:12:49 +09302606 return PLDM_SUCCESS;
2607}
2608
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302609LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302610int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2611 struct pldm_msg *msg)
2612
2613{
2614 if (msg == NULL) {
2615 return PLDM_ERROR_INVALID_DATA;
2616 }
2617
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302618 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302619 header.instance = instance_id;
2620 header.msg_type = PLDM_RESPONSE;
2621 header.pldm_type = PLDM_PLATFORM;
2622 header.command = PLDM_SET_EVENT_RECEIVER;
2623
2624 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2625 if (rc != PLDM_SUCCESS) {
2626 return rc;
2627 }
2628
2629 msg->payload[0] = completion_code;
2630
2631 return PLDM_SUCCESS;
2632}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002633
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302634LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002635int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2636 uint8_t format_version,
2637 uint8_t transfer_operation_flag,
2638 uint32_t data_transfer_handle,
2639 uint16_t event_id_to_acknowledge,
2640 struct pldm_msg *msg,
2641 size_t payload_length)
2642{
2643 struct pldm_msgbuf _buf;
2644 struct pldm_msgbuf *buf = &_buf;
2645 int rc;
2646
2647 if (msg == NULL) {
2648 return PLDM_ERROR_INVALID_DATA;
2649 }
2650
Thu Nguyen387b10f2024-09-24 11:33:16 +00002651 rc = pldm_platform_poll_for_platform_event_message_validate(
2652 transfer_operation_flag, event_id_to_acknowledge);
2653 if (rc < 0) {
2654 return PLDM_ERROR_INVALID_DATA;
2655 }
2656
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302657 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002658 header.msg_type = PLDM_REQUEST;
2659 header.instance = instance_id;
2660 header.pldm_type = PLDM_PLATFORM;
2661 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2662
2663 rc = pack_pldm_header(&header, &(msg->hdr));
2664 if (rc != PLDM_SUCCESS) {
2665 return rc;
2666 }
2667
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302668 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302669 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2670 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002671 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302672 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002673 }
2674
2675 pldm_msgbuf_insert(buf, format_version);
2676 pldm_msgbuf_insert(buf, transfer_operation_flag);
2677 pldm_msgbuf_insert(buf, data_transfer_handle);
2678 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2679
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302680 rc = pldm_msgbuf_destroy(buf);
2681 if (rc) {
2682 return pldm_xlate_errno(rc);
2683 }
2684
2685 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002686}
2687
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302688LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002689int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302690 const struct pldm_msg *msg, size_t payload_length,
2691 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2692 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2693 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2694 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002695{
2696 struct pldm_msgbuf _buf;
2697 struct pldm_msgbuf *buf = &_buf;
2698 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 Jeffery830c1eb2024-10-04 10:48:10 +09302717 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002718 }
2719 if (PLDM_SUCCESS != *completion_code) {
2720 return *completion_code;
2721 }
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 Jeffery830c1eb2024-10-04 10:48:10 +09302726 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002727 }
2728 if ((*event_id == 0) || (*event_id == 0xffff)) {
2729 return PLDM_SUCCESS;
2730 }
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 Jeffery830c1eb2024-10-04 10:48:10 +09302735 return pldm_xlate_errno(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 Jeffery830c1eb2024-10-04 10:48:10 +09302741 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002742 }
2743 if (*event_data_size > payload_length) {
2744 return PLDM_ERROR_INVALID_DATA;
2745 }
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 Jeffery830c1eb2024-10-04 10:48:10 +09302756 rc = pldm_msgbuf_destroy_consumed(buf);
2757 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{
2769 struct pldm_msgbuf _buf;
2770 struct pldm_msgbuf *buf = &_buf;
2771 struct pldm_value_pdr_hdr hdr;
2772 int rc;
2773
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002774 if (!pdr_data || !pdr_value) {
2775 return PLDM_ERROR_INVALID_DATA;
2776 }
2777
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302778 rc = pldm_msgbuf_init_errno(buf,
2779 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2780 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002781 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302782 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002783 }
2784
Andrew Jeffery329176a2024-09-26 22:38:24 +09302785 rc = pldm_msgbuf_extract_value_pdr_hdr(
2786 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
Thu Nguyend4878cd2023-11-09 10:18:33 +07002787 pdr_data_length);
2788 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09302789 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002790 }
2791
2792 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2793
2794 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2795 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2796 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2797 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2798 pldm_msgbuf_extract(buf, pdr_value->container_id);
2799 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2800 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2801 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2802 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2803 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2804 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2805 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2806 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2807 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2808 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2809 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2810 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2811
2812 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2813 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302814 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002815 }
2816 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2817 return PLDM_ERROR_INVALID_DATA;
2818 }
2819
2820 pldm_msgbuf_extract(buf, pdr_value->resolution);
2821 pldm_msgbuf_extract(buf, pdr_value->offset);
2822 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2823 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2824 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2825 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2826 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2827 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2828 pdr_value->max_settable);
2829 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2830 pdr_value->min_settable);
2831
2832 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2833 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302834 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002835 }
2836 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2837 return PLDM_ERROR_INVALID_DATA;
2838 }
2839
2840 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2841 pldm_msgbuf_extract_range_field_format(
2842 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2843 pldm_msgbuf_extract_range_field_format(
2844 buf, pdr_value->range_field_format, pdr_value->normal_max);
2845 pldm_msgbuf_extract_range_field_format(
2846 buf, pdr_value->range_field_format, pdr_value->normal_min);
2847 pldm_msgbuf_extract_range_field_format(
2848 buf, pdr_value->range_field_format, pdr_value->rated_max);
2849 pldm_msgbuf_extract_range_field_format(
2850 buf, pdr_value->range_field_format, pdr_value->rated_min);
2851
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302852 rc = pldm_msgbuf_destroy_consumed(buf);
2853 if (rc) {
2854 return pldm_xlate_errno(rc);
2855 }
2856
2857 return PLDM_SUCCESS;
Thu Nguyend4878cd2023-11-09 10:18:33 +07002858}
Tal Yacobia6fa5552024-05-05 16:57:38 +03002859
Tal Yacobide67ab62024-05-30 22:36:50 +03002860LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002861int encode_get_state_effecter_states_req(uint8_t instance_id,
2862 uint16_t effecter_id,
2863 struct pldm_msg *msg,
2864 size_t payload_length)
2865{
2866 struct pldm_msgbuf _buf;
2867 struct pldm_msgbuf *buf = &_buf;
2868 int rc;
2869
2870 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002871 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002872 }
2873
2874 struct pldm_header_info header = { 0 };
2875 header.msg_type = PLDM_REQUEST;
2876 header.instance = instance_id;
2877 header.pldm_type = PLDM_PLATFORM;
2878 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2879
Tal Yacobif490a382024-05-31 09:57:36 +03002880 rc = pack_pldm_header_errno(&header, &msg->hdr);
2881 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002882 return rc;
2883 }
2884
Tal Yacobif490a382024-05-31 09:57:36 +03002885 rc = pldm_msgbuf_init_errno(buf,
2886 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2887 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002888 if (rc) {
2889 return rc;
2890 }
2891
2892 pldm_msgbuf_insert(buf, effecter_id);
2893
2894 return pldm_msgbuf_destroy_consumed(buf);
2895}
2896
Tal Yacobide67ab62024-05-30 22:36:50 +03002897LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002898int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
2899 size_t payload_length,
2900 uint16_t *effecter_id)
2901{
2902 struct pldm_msgbuf _buf;
2903 struct pldm_msgbuf *buf = &_buf;
2904 int rc;
2905
2906 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002907 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002908 }
2909
Tal Yacobif490a382024-05-31 09:57:36 +03002910 rc = pldm_msgbuf_init_errno(
2911 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2912 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002913 if (rc) {
2914 return rc;
2915 }
2916
2917 pldm_msgbuf_extract_p(buf, effecter_id);
2918
2919 return pldm_msgbuf_destroy_consumed(buf);
2920}
2921
Tal Yacobide67ab62024-05-30 22:36:50 +03002922LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002923int decode_get_state_effecter_states_resp(
2924 const struct pldm_msg *msg, size_t payload_length,
2925 struct pldm_get_state_effecter_states_resp *resp)
2926{
2927 struct pldm_msgbuf _buf;
2928 struct pldm_msgbuf *buf = &_buf;
2929 get_effecter_state_field *field;
2930 int rc;
2931 int i;
2932
2933 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002934 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002935 }
2936
Tal Yacobif490a382024-05-31 09:57:36 +03002937 rc = pldm_msgbuf_init_errno(
2938 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2939 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002940 if (rc) {
2941 return rc;
2942 }
2943
2944 rc = pldm_msgbuf_extract(buf, resp->completion_code);
2945 if (rc) {
2946 return rc;
2947 }
2948
2949 if (PLDM_SUCCESS != resp->completion_code) {
Tal Yacobif490a382024-05-31 09:57:36 +03002950 return 0;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002951 }
2952
2953 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
2954 if (rc) {
2955 return rc;
2956 }
2957
2958 uint8_t comp_effecter_count = resp->comp_effecter_count;
2959
2960 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2961 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002962 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002963 }
2964
2965 for (i = 0, field = resp->field; i < comp_effecter_count;
2966 i++, field++) {
2967 pldm_msgbuf_extract(buf, field->effecter_op_state);
2968 pldm_msgbuf_extract(buf, field->pending_state);
2969 pldm_msgbuf_extract(buf, field->present_state);
2970 }
2971
2972 return pldm_msgbuf_destroy_consumed(buf);
2973}
2974
Tal Yacobide67ab62024-05-30 22:36:50 +03002975LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002976int encode_get_state_effecter_states_resp(
2977 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
2978 struct pldm_msg *msg, size_t payload_length)
2979{
2980 struct pldm_msgbuf _buf;
2981 struct pldm_msgbuf *buf = &_buf;
2982 get_effecter_state_field *field;
2983 int rc;
2984 int i;
2985
2986 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002987 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002988 }
2989
2990 uint8_t comp_effecter_count = resp->comp_effecter_count;
2991
2992 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2993 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002994 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002995 }
2996
2997 struct pldm_header_info header = { 0 };
2998 header.msg_type = PLDM_RESPONSE;
2999 header.instance = instance_id;
3000 header.pldm_type = PLDM_PLATFORM;
3001 header.command = PLDM_GET_STATE_EFFECTER_STATES;
3002
Tal Yacobif490a382024-05-31 09:57:36 +03003003 rc = pack_pldm_header_errno(&header, &msg->hdr);
3004 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03003005 return rc;
3006 }
3007
Tal Yacobif490a382024-05-31 09:57:36 +03003008 rc = pldm_msgbuf_init_errno(
3009 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3010 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003011 if (rc) {
3012 return rc;
3013 }
3014
3015 pldm_msgbuf_insert(buf, resp->completion_code);
3016 pldm_msgbuf_insert(buf, comp_effecter_count);
3017
3018 for (i = 0, field = resp->field; i < comp_effecter_count;
3019 i++, field++) {
3020 pldm_msgbuf_insert(buf, field->effecter_op_state);
3021 pldm_msgbuf_insert(buf, field->pending_state);
3022 pldm_msgbuf_insert(buf, field->present_state);
3023 }
3024
3025 return pldm_msgbuf_destroy_consumed(buf);
3026}
Thu Nguyendacfa352024-06-22 09:53:15 +00003027
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003028LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003029int decode_entity_auxiliary_names_pdr(
3030 const void *data, size_t data_length,
3031 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3032{
3033 struct pldm_msgbuf _buf;
3034 struct pldm_msgbuf *buf = &_buf;
3035 struct pldm_msgbuf _src;
3036 struct pldm_msgbuf *src = &_src;
3037 struct pldm_msgbuf _dst;
3038 struct pldm_msgbuf *dst = &_dst;
3039 size_t names_len = 0;
3040 void *names = NULL;
3041 int rc;
3042 int i;
3043
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003044 if (!data || !pdr) {
3045 return -EINVAL;
3046 }
3047
Thu Nguyendacfa352024-06-22 09:53:15 +00003048 /*
3049 * Alignment of auxiliary_name_data is an invariant as we statically assert
3050 * its behaviour in the header.
3051 */
3052 assert(!((uintptr_t)pdr->auxiliary_name_data &
3053 (alignof(pldm_utf16be) - 1)));
3054
3055 /* Reject any lengths that are obviously invalid */
3056 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3057 return -EINVAL;
3058 }
3059
3060 rc = pldm_msgbuf_init_errno(
3061 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3062 data_length);
3063 if (rc) {
3064 return rc;
3065 }
3066
Andrew Jeffery329176a2024-09-26 22:38:24 +09303067 rc = pldm_msgbuf_extract_value_pdr_hdr(
3068 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
Thu Nguyendacfa352024-06-22 09:53:15 +00003069 data_length);
3070 if (rc) {
3071 return rc;
3072 }
3073
3074 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3075 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3076 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3077 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3078 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3079 if (rc < 0) {
3080 return rc;
3081 }
3082
3083 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3084 if (rc < 0) {
3085 return rc;
3086 }
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003087 assert(names);
Thu Nguyendacfa352024-06-22 09:53:15 +00003088
3089 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3090
3091 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3092 pdr->auxiliary_name_data,
3093 pdr->auxiliary_name_data_size);
3094 if (rc < 0) {
3095 return rc;
3096 }
3097
3098 /*
3099 * Below we do two passes over the same region. This is to first pack the
3100 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3101 * to maintain appropriate alignment.
3102 */
3103
3104 /* Initialise for the first pass to extract the UTF16-BE name strings */
3105 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3106 if (rc < 0) {
3107 return rc;
3108 }
3109
3110 for (i = 0; i < pdr->name_string_count; i++) {
3111 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003112 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3113 if (rc) {
3114 return rc;
3115 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003116 }
3117
3118 rc = pldm_msgbuf_destroy_consumed(src);
3119 if (rc < 0) {
3120 return rc;
3121 }
3122
3123 /* Reinitialise for the second pass to extract the ASCII tag strings */
3124 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3125 if (rc < 0) {
3126 return rc;
3127 }
3128
3129 for (i = 0; i < pdr->name_string_count; i++) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003130 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3131 if (rc) {
3132 return rc;
3133 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003134 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3135 }
3136
3137 if ((rc = pldm_msgbuf_destroy(dst)) ||
3138 (rc = pldm_msgbuf_destroy(src)) ||
3139 (rc = pldm_msgbuf_destroy(buf))) {
3140 return rc;
3141 }
3142
3143 return 0;
3144}
3145
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003146LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003147int decode_pldm_entity_auxiliary_names_pdr_index(
3148 struct pldm_entity_auxiliary_names_pdr *pdr)
3149{
3150 struct pldm_msgbuf _buf;
3151 struct pldm_msgbuf *buf = &_buf;
3152 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
3204 return pldm_msgbuf_destroy_consumed(buf);
3205}
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{
3213 struct pldm_msgbuf _buf;
3214 struct pldm_msgbuf *buf = &_buf;
3215 int rc;
3216
3217 if (!cper_event || !event_data) {
3218 return -EINVAL;
3219 }
3220
3221 if (cper_event_length < sizeof(*cper_event)) {
3222 return -EINVAL;
3223 }
3224
3225 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3226 event_data, event_data_length);
3227 if (rc) {
3228 return rc;
3229 }
3230
3231 pldm_msgbuf_extract(buf, cper_event->format_version);
3232 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3233 if (rc) {
3234 return rc;
3235 }
3236 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3237 cper_event->format_type !=
3238 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3239 return -EPROTO;
3240 }
3241
3242 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3243 if (rc) {
3244 return rc;
3245 }
3246
3247 if (cper_event->event_data_length >
3248 (cper_event_length - sizeof(*cper_event))) {
3249 return -EOVERFLOW;
3250 }
3251
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003252 rc = pldm_msgbuf_extract_array_uint8(
3253 buf, cper_event->event_data_length, cper_event->event_data,
3254 cper_event_length - sizeof(*cper_event));
3255 if (rc) {
3256 return rc;
3257 }
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003258
3259 return pldm_msgbuf_destroy_consumed(buf);
3260}
3261
Thu Nguyen3559aa12024-08-29 00:13:38 +00003262LIBPLDM_ABI_STABLE
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003263uint8_t *
3264pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3265{
3266 return event->event_data;
3267}