blob: 850ed7182b222d1fb6c6a476ce87ad839e17bc86 [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{
96 // Encode possible states
97
98 size_t calculated_possible_states_size = 0;
99
100 {
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930101 char *states_ptr = (char *)possible_states;
102 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930103
104 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
105 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930106 (struct state_sensor_possible_states *)
107 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930108
109 HTOLE16(states->state_set_id);
110
111 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930112 (sizeof(*states) - sizeof(states->states) +
113 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930114 }
115
116 calculated_possible_states_size = states_ptr - begin_states_ptr;
117 }
118
119 // Check lengths
120
121 if (possible_states_size != calculated_possible_states_size) {
122 *actual_size = 0;
123 return PLDM_ERROR;
124 }
125
126 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
127 possible_states_size - sizeof(sensor->possible_states));
128
129 if (allocation_size < *actual_size) {
130 *actual_size = 0;
131 return PLDM_ERROR_INVALID_LENGTH;
132 }
133
134 // Encode rest of PDR
135
136 sensor->hdr.version = 1;
137 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
138 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
139
140 memcpy(sensor->possible_states, possible_states, possible_states_size);
141
142 // Convert sensor PDR body
143 HTOLE16(sensor->terminus_handle);
144 HTOLE16(sensor->sensor_id);
145 HTOLE16(sensor->entity_type);
146 HTOLE16(sensor->entity_instance);
147 HTOLE16(sensor->container_id);
148
149 // Convert header
150 HTOLE32(sensor->hdr.record_handle);
151 HTOLE16(sensor->hdr.record_change_num);
152 HTOLE16(sensor->hdr.length);
153
154 return PLDM_SUCCESS;
155}
156
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930157LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930158int encode_set_state_effecter_states_resp(uint8_t instance_id,
159 uint8_t completion_code,
160 struct pldm_msg *msg)
161{
162 if (msg == NULL) {
163 return PLDM_ERROR_INVALID_DATA;
164 }
165
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930166 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930167 header.msg_type = PLDM_RESPONSE;
168 header.instance = instance_id;
169 header.pldm_type = PLDM_PLATFORM;
170 header.command = PLDM_SET_STATE_EFFECTER_STATES;
171
172 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
173 if (rc != PLDM_SUCCESS) {
174 return rc;
175 }
176
177 msg->payload[0] = completion_code;
178
179 return PLDM_SUCCESS;
180}
181
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930182LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930183int encode_set_state_effecter_states_req(uint8_t instance_id,
184 uint16_t effecter_id,
185 uint8_t comp_effecter_count,
186 set_effecter_state_field *field,
187 struct pldm_msg *msg)
188{
189 if (msg == NULL) {
190 return PLDM_ERROR_INVALID_DATA;
191 }
192
193 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
194 field == NULL) {
195 return PLDM_ERROR_INVALID_DATA;
196 }
197
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930198 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930199 header.msg_type = PLDM_REQUEST;
200 header.instance = instance_id;
201 header.pldm_type = PLDM_PLATFORM;
202 header.command = PLDM_SET_STATE_EFFECTER_STATES;
203
204 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
205 if (rc != PLDM_SUCCESS) {
206 return rc;
207 }
208
209 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930210 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930211 effecter_id = htole16(effecter_id);
212 request->effecter_id = effecter_id;
213 request->comp_effecter_count = comp_effecter_count;
214 memcpy(request->field, field,
215 (sizeof(set_effecter_state_field) * comp_effecter_count));
216
217 return PLDM_SUCCESS;
218}
219
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930220LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930221int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
222 size_t payload_length,
223 uint8_t *completion_code)
224{
225 if (msg == NULL || completion_code == NULL) {
226 return PLDM_ERROR_INVALID_DATA;
227 }
228
229 *completion_code = msg->payload[0];
230 if (PLDM_SUCCESS != *completion_code) {
231 return PLDM_SUCCESS;
232 }
233
234 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
235 return PLDM_ERROR_INVALID_LENGTH;
236 }
237
238 return PLDM_SUCCESS;
239}
240
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930241#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930242LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930243int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
244 size_t payload_length,
245 uint16_t *effecter_id,
246 uint8_t *comp_effecter_count,
247 set_effecter_state_field *field)
248{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930249 struct pldm_msgbuf _buf;
250 struct pldm_msgbuf *buf = &_buf;
251 int rc;
252 int i;
253
Andrew Jeffery9c766792022-08-10 23:12:49 +0930254 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
255 field == NULL) {
256 return PLDM_ERROR_INVALID_DATA;
257 }
258
259 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
260 return PLDM_ERROR_INVALID_LENGTH;
261 }
262
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930263 rc = pldm_msgbuf_init_errno(buf,
264 PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
265 msg->payload, payload_length);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930266 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930267 return pldm_xlate_errno(rc);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930268 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930269
Andrew Jeffery66c77232024-04-24 11:42:02 +0930270 pldm_msgbuf_extract_p(buf, effecter_id);
271 pldm_msgbuf_extract_p(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930272
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930273 if (*comp_effecter_count > 8) {
274 return PLDM_ERROR_INVALID_DATA;
275 }
276
277 for (i = 0; i < *comp_effecter_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930278 pldm_msgbuf_extract(buf, field[i].set_request);
279 pldm_msgbuf_extract(buf, field[i].effecter_state);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930280 }
281
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930282 rc = pldm_msgbuf_destroy(buf);
283 if (rc) {
284 return pldm_xlate_errno(rc);
285 }
286
287 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930288}
289
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930290LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930291int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
292 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
293 uint8_t *transfer_op_flag, uint16_t *request_cnt,
294 uint16_t *record_chg_num)
295{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930296 struct pldm_msgbuf _buf;
297 struct pldm_msgbuf *buf = &_buf;
298 int rc;
299
Andrew Jeffery9c766792022-08-10 23:12:49 +0930300 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
301 transfer_op_flag == NULL || request_cnt == NULL ||
302 record_chg_num == NULL) {
303 return PLDM_ERROR_INVALID_DATA;
304 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930305
Andrew Jeffery9c766792022-08-10 23:12:49 +0930306 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
307 return PLDM_ERROR_INVALID_LENGTH;
308 }
309
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930310 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
311 payload_length);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930312 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930313 return pldm_xlate_errno(rc);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930314 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930315
Andrew Jeffery66c77232024-04-24 11:42:02 +0930316 pldm_msgbuf_extract_p(buf, record_hndl);
317 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
318 pldm_msgbuf_extract_p(buf, transfer_op_flag);
319 pldm_msgbuf_extract_p(buf, request_cnt);
320 pldm_msgbuf_extract_p(buf, record_chg_num);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930321
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930322 rc = pldm_msgbuf_destroy(buf);
323 if (rc) {
324 return pldm_xlate_errno(rc);
325 }
326
327 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930328}
329
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930330LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930331int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
332 uint32_t next_record_hndl,
333 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
334 uint16_t resp_cnt, const uint8_t *record_data,
335 uint8_t transfer_crc, struct pldm_msg *msg)
336{
337 if (msg == NULL) {
338 return PLDM_ERROR_INVALID_DATA;
339 }
340
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930341 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930342 header.msg_type = PLDM_RESPONSE;
343 header.instance = instance_id;
344 header.pldm_type = PLDM_PLATFORM;
345 header.command = PLDM_GET_PDR;
346
347 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
348 if (rc != PLDM_SUCCESS) {
349 return rc;
350 }
351
352 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930353 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930354 response->completion_code = completion_code;
355
356 if (response->completion_code == PLDM_SUCCESS) {
357 response->next_record_handle = htole32(next_record_hndl);
358 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930359 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930360 response->transfer_flag = transfer_flag;
361 response->response_count = htole16(resp_cnt);
362 if (record_data != NULL && resp_cnt > 0) {
363 memcpy(response->record_data, record_data, resp_cnt);
364 }
365 if (transfer_flag == PLDM_END) {
366 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930367 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
368 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930369 *dst = transfer_crc;
370 }
371 }
372
373 return PLDM_SUCCESS;
374}
375
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930376LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930377int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930378 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
379 const uint8_t *update_time, const uint8_t *oem_update_time,
380 uint32_t record_count, uint32_t repository_size,
381 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
382 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930383{
384 if (msg == NULL) {
385 return PLDM_ERROR_INVALID_DATA;
386 }
387
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930388 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930389 header.msg_type = PLDM_RESPONSE;
390 header.instance = instance_id;
391 header.pldm_type = PLDM_PLATFORM;
392 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
393
394 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
395 if (rc != PLDM_SUCCESS) {
396 return rc;
397 }
398
399 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930400 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930401 response->completion_code = completion_code;
402
403 if (response->completion_code == PLDM_SUCCESS) {
404 response->repository_state = repository_state;
405 if (update_time != NULL) {
406 memcpy(response->update_time, update_time,
407 PLDM_TIMESTAMP104_SIZE);
408 }
409 if (oem_update_time != NULL) {
410 memcpy(response->oem_update_time, oem_update_time,
411 PLDM_TIMESTAMP104_SIZE);
412 }
413 response->record_count = htole32(record_count);
414 response->repository_size = htole32(repository_size);
415 response->largest_record_size = htole32(largest_record_size);
416 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930417 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930418 }
419
420 return PLDM_SUCCESS;
421}
422
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000423LIBPLDM_ABI_DEPRECATED
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800424int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930425 const struct pldm_msg *msg, size_t payload_length,
426 uint8_t *completion_code, uint8_t *repository_state,
427 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
428 uint32_t *repository_size, uint32_t *largest_record_size,
429 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800430{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930431 struct pldm_msgbuf _buf;
432 struct pldm_msgbuf *buf = &_buf;
433 int rc;
434
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800435 if (msg == NULL || completion_code == NULL ||
436 repository_state == NULL || update_time == NULL ||
437 oem_update_time == NULL || record_count == NULL ||
438 repository_size == NULL || largest_record_size == NULL ||
439 data_transfer_handle_timeout == NULL) {
440 return PLDM_ERROR_INVALID_DATA;
441 }
442
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930443 rc = pldm_msgbuf_init_errno(buf,
444 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
445 msg->payload, payload_length);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930446 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930447 return pldm_xlate_errno(rc);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930448 }
449
Andrew Jeffery66c77232024-04-24 11:42:02 +0930450 pldm_msgbuf_extract_p(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800451 if (PLDM_SUCCESS != *completion_code) {
452 return PLDM_SUCCESS;
453 }
454
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930455 rc = pldm_msgbuf_extract_p(buf, repository_state);
456 if (rc) {
457 return pldm_xlate_errno(rc);
458 }
459
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800460 if (*repository_state > PLDM_FAILED) {
461 return PLDM_ERROR_INVALID_DATA;
462 }
463
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000464 /* NOTE: Memory safety */
465 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
466 PLDM_TIMESTAMP104_SIZE);
467 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930468 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000469 }
470
471 /* NOTE: Memory safety */
472 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
473 oem_update_time, PLDM_TIMESTAMP104_SIZE);
474 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930475 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000476 }
477
Andrew Jeffery66c77232024-04-24 11:42:02 +0930478 pldm_msgbuf_extract_p(buf, record_count);
479 pldm_msgbuf_extract_p(buf, repository_size);
480 pldm_msgbuf_extract_p(buf, largest_record_size);
481 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800482
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930483 rc = pldm_msgbuf_destroy(buf);
484 if (rc) {
485 return pldm_xlate_errno(rc);
486 }
487
488 return PLDM_SUCCESS;
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800489}
490
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000491LIBPLDM_ABI_TESTING
492int decode_get_pdr_repository_info_resp_safe(
493 const struct pldm_msg *msg, size_t payload_length,
494 struct pldm_pdr_repository_info_resp *resp)
495{
496 struct pldm_msgbuf _buf;
497 struct pldm_msgbuf *buf = &_buf;
498 int rc;
499
500 if (msg == NULL || resp == NULL) {
501 return -EINVAL;
502 }
503
504 rc = pldm_msg_has_error(msg, payload_length);
505 if (rc) {
506 resp->completion_code = rc;
507 return 0;
508 }
509
510 rc = pldm_msgbuf_init_errno(buf,
511 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
512 msg->payload, payload_length);
513 if (rc) {
514 return rc;
515 }
516
517 rc = pldm_msgbuf_extract(buf, resp->completion_code);
518 if (rc) {
519 return rc;
520 }
521
522 pldm_msgbuf_extract(buf, resp->repository_state);
523
524 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
525 resp->update_time,
526 sizeof(resp->update_time));
527 if (rc) {
528 return rc;
529 }
530
531 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
532 resp->oem_update_time,
533 sizeof(resp->oem_update_time));
534 if (rc) {
535 return rc;
536 }
537
538 pldm_msgbuf_extract(buf, resp->record_count);
539 pldm_msgbuf_extract(buf, resp->repository_size);
540 pldm_msgbuf_extract(buf, resp->largest_record_size);
541 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
542
543 return pldm_msgbuf_destroy_consumed(buf);
544}
545
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930546LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930547int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
548 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
549 uint16_t request_cnt, uint16_t record_chg_num,
550 struct pldm_msg *msg, size_t payload_length)
551{
552 if (msg == NULL) {
553 return PLDM_ERROR_INVALID_DATA;
554 }
555
556 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
557 return PLDM_ERROR_INVALID_LENGTH;
558 }
559
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930560 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930561 header.msg_type = PLDM_REQUEST;
562 header.instance = instance_id;
563 header.pldm_type = PLDM_PLATFORM;
564 header.command = PLDM_GET_PDR;
565
566 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
567 if (rc != PLDM_SUCCESS) {
568 return rc;
569 }
570
571 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930572 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930573 request->record_handle = htole32(record_hndl);
574 request->data_transfer_handle = htole32(data_transfer_hndl);
575 request->transfer_op_flag = transfer_op_flag;
576 request->request_count = htole16(request_cnt);
577 request->record_change_number = htole16(record_chg_num);
578
579 return PLDM_SUCCESS;
580}
581
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000582LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930583int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
584 uint8_t *completion_code, uint32_t *next_record_hndl,
585 uint32_t *next_data_transfer_hndl,
586 uint8_t *transfer_flag, uint16_t *resp_cnt,
587 uint8_t *record_data, size_t record_data_length,
588 uint8_t *transfer_crc)
589{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930590 struct pldm_msgbuf _buf;
591 struct pldm_msgbuf *buf = &_buf;
592 int rc;
593
Andrew Jeffery9c766792022-08-10 23:12:49 +0930594 if (msg == NULL || completion_code == NULL ||
595 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
596 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
597 return PLDM_ERROR_INVALID_DATA;
598 }
599
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930600 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
601 msg->payload, payload_length);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930602 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930603 return pldm_xlate_errno(rc);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930604 }
605
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930606 rc = pldm_msgbuf_extract_p(buf, completion_code);
607 if (rc) {
608 return pldm_xlate_errno(rc);
609 }
610
Andrew Jeffery9c766792022-08-10 23:12:49 +0930611 if (PLDM_SUCCESS != *completion_code) {
612 return PLDM_SUCCESS;
613 }
614
Andrew Jeffery66c77232024-04-24 11:42:02 +0930615 pldm_msgbuf_extract_p(buf, next_record_hndl);
616 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
617 pldm_msgbuf_extract_p(buf, transfer_flag);
618 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930619 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930620 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930621 }
622
623 if (*resp_cnt > 0 && record_data != NULL) {
624 if (record_data_length < *resp_cnt) {
625 return PLDM_ERROR_INVALID_LENGTH;
626 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000627 /* NOTE: Memory safety */
628 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
629 *resp_cnt);
630 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930631 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000632 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930633 }
634
635 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930636 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930637 }
638
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930639 rc = pldm_msgbuf_destroy(buf);
640 if (rc) {
641 return pldm_xlate_errno(rc);
642 }
643
644 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930645}
646
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000647LIBPLDM_ABI_TESTING
648int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
649 struct pldm_get_pdr_resp *resp, size_t resp_len,
650 uint8_t *transfer_crc)
651{
652 struct pldm_msgbuf _buf;
653 struct pldm_msgbuf *buf = &_buf;
654 int rc;
655
656 if (msg == NULL || resp == NULL || transfer_crc == NULL) {
657 return -EINVAL;
658 }
659
660 rc = pldm_msg_has_error(msg, payload_length);
661 if (rc) {
662 resp->completion_code = rc;
663 return 0;
664 }
665
666 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
667 msg->payload, payload_length);
668 if (rc) {
669 return rc;
670 }
671
672 pldm_msgbuf_extract(buf, resp->completion_code);
673 pldm_msgbuf_extract(buf, resp->next_record_handle);
674 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
675
676 rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
677 if (rc) {
678 return rc;
679 }
680
681 rc = pldm_msgbuf_extract(buf, resp->response_count);
682 if (rc) {
683 return rc;
684 }
685
686 rc = pldm_msgbuf_extract_array(
687 buf, resp->response_count, resp->record_data,
688 resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
689 if (rc) {
690 return rc;
691 }
692
693 if (resp->transfer_flag == PLDM_END) {
694 pldm_msgbuf_extract_p(buf, transfer_crc);
695 }
696
697 return pldm_msgbuf_destroy_consumed(buf);
698}
699
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930700LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930701int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
702 size_t payload_length,
703 uint16_t *effecter_id,
704 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930705 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930706{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930707 struct pldm_msgbuf _buf;
708 struct pldm_msgbuf *buf = &_buf;
709 int rc;
710
Andrew Jeffery9c766792022-08-10 23:12:49 +0930711 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
712 effecter_value == NULL) {
713 return PLDM_ERROR_INVALID_DATA;
714 }
715
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930716 rc = pldm_msgbuf_init_errno(
717 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
718 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930719 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930720 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930721 }
722
Andrew Jeffery66c77232024-04-24 11:42:02 +0930723 pldm_msgbuf_extract_p(buf, effecter_id);
724 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930725 if (rc) {
726 return PLDM_ERROR_INVALID_DATA;
727 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930728
729 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
730 return PLDM_ERROR_INVALID_DATA;
731 }
732
Andrew Jeffery3884c442023-04-12 11:13:24 +0930733 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
734 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930735
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930736 rc = pldm_msgbuf_destroy(buf);
737 if (rc) {
738 return pldm_xlate_errno(rc);
739 }
740
741 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930742}
743
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930744LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930745int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
746 uint8_t completion_code,
747 struct pldm_msg *msg,
748 size_t payload_length)
749{
750 if (msg == NULL) {
751 return PLDM_ERROR_INVALID_DATA;
752 }
753
754 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
755 return PLDM_ERROR_INVALID_LENGTH;
756 }
757
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930758 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930759 header.msg_type = PLDM_RESPONSE;
760 header.instance = instance_id;
761 header.pldm_type = PLDM_PLATFORM;
762 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
763
764 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
765 if (rc != PLDM_SUCCESS) {
766 return rc;
767 }
768
769 msg->payload[0] = completion_code;
770
771 return rc;
772}
773
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930774LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930775int encode_set_numeric_effecter_value_req(uint8_t instance_id,
776 uint16_t effecter_id,
777 uint8_t effecter_data_size,
778 const uint8_t *effecter_value,
779 struct pldm_msg *msg,
780 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930781{
782 if (msg == NULL || effecter_value == NULL) {
783 return PLDM_ERROR_INVALID_DATA;
784 }
785
786 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
787 return PLDM_ERROR_INVALID_DATA;
788 }
789
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930790 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930791 header.msg_type = PLDM_REQUEST;
792 header.instance = instance_id;
793 header.pldm_type = PLDM_PLATFORM;
794 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
795
796 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
797 if (rc != PLDM_SUCCESS) {
798 return rc;
799 }
800
801 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930802 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930803 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
804 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
805 if (payload_length !=
806 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
807 return PLDM_ERROR_INVALID_LENGTH;
808 }
809 request->effecter_value[0] = *effecter_value;
810 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
811 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
812 if (payload_length !=
813 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
814 return PLDM_ERROR_INVALID_LENGTH;
815 }
816
817 uint16_t val = *(uint16_t *)(effecter_value);
818 val = htole16(val);
819 memcpy(request->effecter_value, &val, sizeof(uint16_t));
820
821 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
822 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
823 if (payload_length !=
824 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
825 return PLDM_ERROR_INVALID_LENGTH;
826 }
827
828 uint32_t val = *(uint32_t *)(effecter_value);
829 val = htole32(val);
830 memcpy(request->effecter_value, &val, sizeof(uint32_t));
831 }
832
833 request->effecter_id = htole16(effecter_id);
834 request->effecter_data_size = effecter_data_size;
835
836 return PLDM_SUCCESS;
837}
838
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930839LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930840int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
841 size_t payload_length,
842 uint8_t *completion_code)
843{
844 if (msg == NULL || completion_code == NULL) {
845 return PLDM_ERROR_INVALID_DATA;
846 }
847
848 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
849 return PLDM_ERROR_INVALID_LENGTH;
850 }
851
852 *completion_code = msg->payload[0];
853
854 return PLDM_SUCCESS;
855}
856
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930857LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930858int encode_get_state_sensor_readings_resp(uint8_t instance_id,
859 uint8_t completion_code,
860 uint8_t comp_sensor_count,
861 get_sensor_state_field *field,
862 struct pldm_msg *msg)
863{
864 if (msg == NULL) {
865 return PLDM_ERROR_INVALID_DATA;
866 }
867
868 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
869 return PLDM_ERROR_INVALID_DATA;
870 }
871
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930872 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930873 header.msg_type = PLDM_RESPONSE;
874 header.instance = instance_id;
875 header.pldm_type = PLDM_PLATFORM;
876 header.command = PLDM_GET_STATE_SENSOR_READINGS;
877
878 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
879 if (rc != PLDM_SUCCESS) {
880 return rc;
881 }
882
883 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930884 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930885
886 response->completion_code = completion_code;
887 response->comp_sensor_count = comp_sensor_count;
888 memcpy(response->field, field,
889 (sizeof(get_sensor_state_field) * comp_sensor_count));
890
891 return PLDM_SUCCESS;
892}
893
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930894LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930895int encode_get_state_sensor_readings_req(uint8_t instance_id,
896 uint16_t sensor_id,
897 bitfield8_t sensor_rearm,
898 uint8_t reserved, struct pldm_msg *msg)
899{
900 if (msg == NULL) {
901 return PLDM_ERROR_INVALID_DATA;
902 }
903
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930904 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930905 header.msg_type = PLDM_REQUEST;
906 header.instance = instance_id;
907 header.pldm_type = PLDM_PLATFORM;
908 header.command = PLDM_GET_STATE_SENSOR_READINGS;
909
910 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
911 if (rc != PLDM_SUCCESS) {
912 return rc;
913 }
914
915 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930916 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930917
918 request->sensor_id = htole16(sensor_id);
919 request->reserved = reserved;
920 request->sensor_rearm = sensor_rearm;
921
922 return PLDM_SUCCESS;
923}
924
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930925LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930926int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
927 size_t payload_length,
928 uint8_t *completion_code,
929 uint8_t *comp_sensor_count,
930 get_sensor_state_field *field)
931{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930932 struct pldm_msgbuf _buf;
933 struct pldm_msgbuf *buf = &_buf;
934 uint8_t i;
935 int rc;
936
Andrew Jeffery9c766792022-08-10 23:12:49 +0930937 if (msg == NULL || completion_code == NULL ||
938 comp_sensor_count == NULL || field == NULL) {
939 return PLDM_ERROR_INVALID_DATA;
940 }
941
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930942 rc = pldm_msgbuf_init_errno(
943 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
944 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930945 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930946 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930947 }
948
Andrew Jeffery66c77232024-04-24 11:42:02 +0930949 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930950 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930951 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930952 }
953
Andrew Jeffery9c766792022-08-10 23:12:49 +0930954 if (PLDM_SUCCESS != *completion_code) {
955 return PLDM_SUCCESS;
956 }
957
Andrew Jeffery66c77232024-04-24 11:42:02 +0930958 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
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 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930962
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930963 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930964 return PLDM_ERROR_INVALID_DATA;
965 }
966
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930967 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930968 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
969 pldm_msgbuf_extract(buf, field[i].present_state);
970 pldm_msgbuf_extract(buf, field[i].previous_state);
971 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930972 }
973
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930974 rc = pldm_msgbuf_destroy_consumed(buf);
975 if (rc) {
976 return pldm_xlate_errno(rc);
977 }
978
979 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930980}
981
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930982LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930983int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
984 size_t payload_length,
985 uint16_t *sensor_id,
986 bitfield8_t *sensor_rearm,
987 uint8_t *reserved)
988{
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930989 struct pldm_msgbuf _buf;
990 struct pldm_msgbuf *buf = &_buf;
991 int rc;
992
Andrew Jeffery9c766792022-08-10 23:12:49 +0930993 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
994 return PLDM_ERROR_INVALID_DATA;
995 }
996
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930997 rc = pldm_msgbuf_init_errno(buf,
998 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
999 msg->payload, payload_length);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301000 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301001 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301002 }
1003
Andrew Jeffery66c77232024-04-24 11:42:02 +09301004 pldm_msgbuf_extract_p(buf, sensor_id);
1005 pldm_msgbuf_extract(buf, sensor_rearm->byte);
1006 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301007
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301008 rc = pldm_msgbuf_destroy(buf);
1009 if (rc) {
1010 return pldm_xlate_errno(rc);
1011 }
1012
1013 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301014}
1015
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301016LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301017int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301018 struct pldm_sensor_event_data *const event_data,
1019 const size_t event_data_size, const uint16_t sensor_id,
1020 const enum sensor_event_class_states sensor_event_class,
1021 const uint8_t sensor_offset, const uint8_t event_state,
1022 const uint8_t previous_event_state,
1023 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301024{
1025 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301026 (sizeof(*event_data) - sizeof(event_data->event_class) +
1027 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301028
1029 if (!event_data) {
1030 return PLDM_SUCCESS;
1031 }
1032
1033 if (event_data_size < *actual_event_data_size) {
1034 *actual_event_data_size = 0;
1035 return PLDM_ERROR_INVALID_LENGTH;
1036 }
1037
1038 event_data->sensor_id = htole16(sensor_id);
1039 event_data->sensor_event_class_type = sensor_event_class;
1040
1041 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301042 (struct pldm_sensor_event_state_sensor_state *)
1043 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301044
1045 state_data->sensor_offset = sensor_offset;
1046 state_data->event_state = event_state;
1047 state_data->previous_event_state = previous_event_state;
1048
1049 return PLDM_SUCCESS;
1050}
1051
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301052LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301053int decode_platform_event_message_req(const struct pldm_msg *msg,
1054 size_t payload_length,
1055 uint8_t *format_version, uint8_t *tid,
1056 uint8_t *event_class,
1057 size_t *event_data_offset)
1058{
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301059 struct pldm_msgbuf _buf;
1060 struct pldm_msgbuf *buf = &_buf;
1061 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301062
1063 if (msg == NULL || format_version == NULL || tid == NULL ||
1064 event_class == NULL || event_data_offset == NULL) {
1065 return PLDM_ERROR_INVALID_DATA;
1066 }
1067
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301068 rc = pldm_msgbuf_init_errno(buf,
1069 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
1070 msg->payload, payload_length);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301071 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301072 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301073 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301074
Andrew Jeffery66c77232024-04-24 11:42:02 +09301075 pldm_msgbuf_extract_p(buf, format_version);
1076 pldm_msgbuf_extract_p(buf, tid);
1077 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301078
1079 rc = pldm_msgbuf_destroy(buf);
1080 if (rc) {
1081 return pldm_xlate_errno(rc);
1082 }
1083
Andrew Jeffery9c766792022-08-10 23:12:49 +09301084 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301085 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301086
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301087 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301088}
1089
Thu Nguyen387b10f2024-09-24 11:33:16 +00001090static int pldm_platform_poll_for_platform_event_message_validate(
1091 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1092{
1093 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1094 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1095 ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1096 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1097 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
Thu Nguyen9e16b182024-10-01 03:12:16 +00001098 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1099 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1100 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
Thu Nguyen387b10f2024-09-24 11:33:16 +00001101 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1102 return -EPROTO;
1103 }
1104
1105 return 0;
1106}
1107
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301108LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001109int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301110 const struct pldm_msg *msg, size_t payload_length,
1111 uint8_t *format_version, uint8_t *transfer_operation_flag,
1112 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001113{
1114 struct pldm_msgbuf _buf;
1115 struct pldm_msgbuf *buf = &_buf;
1116 int rc;
1117
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001118 if (msg == NULL || format_version == NULL ||
1119 transfer_operation_flag == NULL || data_transfer_handle == NULL ||
1120 event_id_to_acknowledge == NULL) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001121 return PLDM_ERROR_INVALID_DATA;
1122 }
1123
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301124 rc = pldm_msgbuf_init_errno(
1125 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
1126 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001127 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301128 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001129 }
1130
Andrew Jeffery66c77232024-04-24 11:42:02 +09301131 pldm_msgbuf_extract_p(buf, format_version);
1132 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001133 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301134 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001135 }
1136 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
1137 return PLDM_ERROR_INVALID_DATA;
1138 }
1139
Andrew Jeffery66c77232024-04-24 11:42:02 +09301140 pldm_msgbuf_extract_p(buf, data_transfer_handle);
1141 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
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
Thu Nguyen387b10f2024-09-24 11:33:16 +00001146 rc = pldm_platform_poll_for_platform_event_message_validate(
1147 *transfer_operation_flag, *event_id_to_acknowledge);
1148 if (rc < 0) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001149 return PLDM_ERROR_INVALID_DATA;
1150 }
1151
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301152 rc = pldm_msgbuf_destroy(buf);
1153 if (rc) {
1154 return pldm_xlate_errno(rc);
1155 }
1156
1157 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001158}
1159
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301160LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301161int encode_platform_event_message_resp(uint8_t instance_id,
1162 uint8_t completion_code,
1163 uint8_t platform_event_status,
1164 struct pldm_msg *msg)
1165{
1166 if (msg == NULL) {
1167 return PLDM_ERROR_INVALID_DATA;
1168 }
1169
1170 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1171 return PLDM_ERROR_INVALID_DATA;
1172 }
1173
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301174 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301175 header.msg_type = PLDM_RESPONSE;
1176 header.instance = instance_id;
1177 header.pldm_type = PLDM_PLATFORM;
1178 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1179
1180 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1181 if (rc != PLDM_SUCCESS) {
1182 return rc;
1183 }
1184
1185 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301186 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301187 response->completion_code = completion_code;
1188 response->platform_event_status = platform_event_status;
1189
1190 return PLDM_SUCCESS;
1191}
1192
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301193LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001194int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301195 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1196 uint16_t event_id, uint32_t next_data_transfer_handle,
1197 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1198 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1199 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001200{
1201 struct pldm_msgbuf _buf;
1202 struct pldm_msgbuf *buf = &_buf;
1203 int rc;
1204
1205 if (!msg) {
1206 return PLDM_ERROR_INVALID_DATA;
1207 }
1208
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301209 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001210 header.msg_type = PLDM_RESPONSE;
1211 header.instance = instance_id;
1212 header.pldm_type = PLDM_PLATFORM;
1213 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1214
1215 rc = pack_pldm_header(&header, &(msg->hdr));
1216 if (rc != PLDM_SUCCESS) {
1217 return rc;
1218 }
1219
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301220 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301221 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1222 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001223 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301224 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001225 }
1226
1227 pldm_msgbuf_insert(buf, completion_code);
1228 pldm_msgbuf_insert(buf, tid);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301229 rc = pldm_msgbuf_insert(buf, event_id);
1230 if (rc) {
1231 return pldm_xlate_errno(rc);
1232 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001233
1234 if (event_id == 0xffff || event_id == 0x0000) {
1235 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1236 payload_length) {
1237 return PLDM_ERROR_INVALID_LENGTH;
1238 }
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301239
1240 rc = pldm_msgbuf_destroy(buf);
1241 if (rc) {
1242 return pldm_xlate_errno(rc);
1243 }
1244
1245 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001246 }
1247
1248 if ((event_data == NULL) && (event_data_size > 0)) {
1249 return PLDM_ERROR_INVALID_DATA;
1250 }
1251
1252 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1253 pldm_msgbuf_insert(buf, transfer_flag);
1254 pldm_msgbuf_insert(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301255 rc = pldm_msgbuf_insert(buf, event_data_size);
1256 if (rc) {
1257 return pldm_xlate_errno(rc);
1258 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001259
1260 if ((event_data_size > 0) && event_data) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001261 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
1262 event_data_size);
1263 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301264 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001265 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001266 }
1267
1268 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1269 pldm_msgbuf_insert(buf, checksum);
1270 }
1271
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301272 rc = pldm_msgbuf_destroy(buf);
1273 if (rc) {
1274 return pldm_xlate_errno(rc);
1275 }
1276
1277 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001278}
1279
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301280LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301281int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301282 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1283 uint8_t event_class, const uint8_t *event_data,
1284 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301285
1286{
1287 if (format_version != 1) {
1288 return PLDM_ERROR_INVALID_DATA;
1289 }
1290
1291 if (msg == NULL || event_data == NULL) {
1292 return PLDM_ERROR_INVALID_DATA;
1293 }
1294
1295 if (event_data_length == 0) {
1296 return PLDM_ERROR_INVALID_DATA;
1297 }
1298
Andrew Jeffery225530a2024-09-25 13:11:43 +09301299 if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1300 event_data_length) {
1301 return PLDM_ERROR_INVALID_LENGTH;
1302 }
1303
Andrew Jeffery9c766792022-08-10 23:12:49 +09301304 if (payload_length !=
1305 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1306 return PLDM_ERROR_INVALID_LENGTH;
1307 }
1308
John Chungb43a7782024-09-26 22:04:27 +08001309 if (event_class > PLDM_CPER_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001310 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301311 return PLDM_ERROR_INVALID_DATA;
1312 }
1313
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301314 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301315 header.msg_type = PLDM_REQUEST;
1316 header.instance = instance_id;
1317 header.pldm_type = PLDM_PLATFORM;
1318 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1319
1320 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1321 if (rc != PLDM_SUCCESS) {
1322 return rc;
1323 }
1324
1325 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301326 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301327 request->format_version = format_version;
1328 request->tid = tid;
1329 request->event_class = event_class;
1330 memcpy(request->event_data, event_data, event_data_length);
1331
1332 return PLDM_SUCCESS;
1333}
1334
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301335LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301336int decode_platform_event_message_resp(const struct pldm_msg *msg,
1337 size_t payload_length,
1338 uint8_t *completion_code,
1339 uint8_t *platform_event_status)
1340{
Andrew Jefferye5011772023-04-13 12:06:22 +09301341 struct pldm_msgbuf _buf;
1342 struct pldm_msgbuf *buf = &_buf;
1343 int rc;
1344
Andrew Jeffery9c766792022-08-10 23:12:49 +09301345 if (msg == NULL || completion_code == NULL ||
1346 platform_event_status == NULL) {
1347 return PLDM_ERROR_INVALID_DATA;
1348 }
1349
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301350 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1351 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301352 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301353 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301354 }
1355
Andrew Jeffery66c77232024-04-24 11:42:02 +09301356 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301357 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301358 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301359 }
1360
Andrew Jeffery9c766792022-08-10 23:12:49 +09301361 if (PLDM_SUCCESS != *completion_code) {
1362 return PLDM_SUCCESS;
1363 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301364
Andrew Jeffery66c77232024-04-24 11:42:02 +09301365 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
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 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301369
1370 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1371 return PLDM_ERROR_INVALID_DATA;
1372 }
1373
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301374 rc = pldm_msgbuf_destroy(buf);
1375 if (rc) {
1376 return pldm_xlate_errno(rc);
1377 }
1378
1379 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301380}
1381
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301382LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301383int encode_event_message_buffer_size_req(uint8_t instance_id,
1384 uint16_t event_receiver_max_buffer_size,
1385 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001386{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301387 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001388 header.msg_type = PLDM_REQUEST;
1389 header.instance = instance_id;
1390 header.pldm_type = PLDM_PLATFORM;
1391 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1392
1393 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1394 if (rc != PLDM_SUCCESS) {
1395 return rc;
1396 }
1397
1398 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301399 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001400 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301401 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001402
1403 return PLDM_SUCCESS;
1404}
1405
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301406LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001407int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1408 size_t payload_length,
1409 uint8_t *completion_code,
1410 uint16_t *terminus_max_buffer_size)
1411{
Andrew Jeffery11126902023-04-13 12:12:10 +09301412 struct pldm_msgbuf _buf;
1413 struct pldm_msgbuf *buf = &_buf;
1414 int rc;
1415
Dung Caod6ae8982022-11-02 10:00:10 +07001416 if (msg == NULL || completion_code == NULL ||
1417 terminus_max_buffer_size == NULL) {
1418 return PLDM_ERROR_INVALID_DATA;
1419 }
1420
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301421 rc = pldm_msgbuf_init_errno(buf,
1422 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1423 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301424 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301425 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301426 }
1427
Andrew Jeffery66c77232024-04-24 11:42:02 +09301428 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301429 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301430 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301431 }
1432
Dung Caod6ae8982022-11-02 10:00:10 +07001433 if (PLDM_SUCCESS != *completion_code) {
1434 return PLDM_SUCCESS;
1435 }
Dung Caod6ae8982022-11-02 10:00:10 +07001436
Andrew Jeffery66c77232024-04-24 11:42:02 +09301437 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001438
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301439 rc = pldm_msgbuf_destroy_consumed(buf);
1440 if (rc) {
1441 return pldm_xlate_errno(rc);
1442 }
1443
1444 return PLDM_SUCCESS;
Dung Caod6ae8982022-11-02 10:00:10 +07001445}
1446
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301447LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001448int encode_event_message_supported_req(uint8_t instance_id,
1449 uint8_t format_version,
1450 struct pldm_msg *msg)
1451{
1452 if (format_version != 1) {
1453 return PLDM_ERROR_INVALID_DATA;
1454 }
1455
1456 if (msg == NULL) {
1457 return PLDM_ERROR_INVALID_DATA;
1458 }
1459
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301460 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001461 header.msg_type = PLDM_REQUEST;
1462 header.instance = instance_id;
1463 header.pldm_type = PLDM_PLATFORM;
1464 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1465
1466 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1467 if (rc != PLDM_SUCCESS) {
1468 return rc;
1469 }
1470
1471 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301472 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001473 request->format_version = format_version;
1474
1475 return PLDM_SUCCESS;
1476}
1477
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301478LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301479int decode_event_message_supported_resp(const struct pldm_msg *msg,
1480 size_t payload_length,
1481 uint8_t *completion_code,
1482 uint8_t *synchrony_config,
1483 bitfield8_t *synchrony_config_support,
1484 uint8_t *number_event_class_returned,
1485 uint8_t *event_class,
1486 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001487{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301488 struct pldm_msgbuf _buf;
1489 struct pldm_msgbuf *buf = &_buf;
1490 int i;
1491 int rc;
1492
Dung Cao1bf8c872022-11-29 05:32:58 +07001493 if (msg == NULL || completion_code == NULL ||
1494 synchrony_config == NULL || synchrony_config_support == NULL ||
1495 number_event_class_returned == NULL || event_class == NULL) {
1496 return PLDM_ERROR_INVALID_DATA;
1497 }
1498
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301499 rc = pldm_msgbuf_init_errno(buf,
1500 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1501 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301502 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301503 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301504 }
1505
Andrew Jeffery66c77232024-04-24 11:42:02 +09301506 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301507 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301508 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301509 }
1510
Dung Cao1bf8c872022-11-29 05:32:58 +07001511 if (PLDM_SUCCESS != *completion_code) {
1512 return PLDM_SUCCESS;
1513 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301514
Andrew Jeffery66c77232024-04-24 11:42:02 +09301515 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301516 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301517 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001518 }
1519
Dung Cao1bf8c872022-11-29 05:32:58 +07001520 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1521 return PLDM_ERROR_INVALID_DATA;
1522 }
1523
Andrew Jeffery66c77232024-04-24 11:42:02 +09301524 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001525
Andrew Jeffery66c77232024-04-24 11:42:02 +09301526 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301527 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301528 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001529 }
1530
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301531 if (*number_event_class_returned == 0) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301532 rc = pldm_msgbuf_destroy(buf);
1533 if (rc) {
1534 return pldm_xlate_errno(rc);
1535 }
1536
1537 return PLDM_SUCCESS;
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301538 }
1539
1540 if (event_class_count < *number_event_class_returned) {
1541 return PLDM_ERROR_INVALID_LENGTH;
1542 }
1543
1544 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301545 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301546 }
1547
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301548 rc = pldm_msgbuf_destroy_consumed(buf);
1549 if (rc) {
1550 return pldm_xlate_errno(rc);
1551 }
1552
1553 return PLDM_SUCCESS;
Dung Cao1bf8c872022-11-29 05:32:58 +07001554}
1555
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301556LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301557int decode_sensor_event_data(const uint8_t *event_data,
1558 size_t event_data_length, uint16_t *sensor_id,
1559 uint8_t *sensor_event_class_type,
1560 size_t *event_class_data_offset)
1561{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301562 struct pldm_msgbuf _buf;
1563 struct pldm_msgbuf *buf = &_buf;
1564 int rc;
1565
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001566 if (event_data == NULL || sensor_id == NULL ||
1567 sensor_event_class_type == NULL ||
1568 event_class_data_offset == NULL) {
1569 return PLDM_ERROR_INVALID_DATA;
1570 }
1571
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301572 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1573 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301574 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301575 return pldm_xlate_errno(rc);
1576 }
1577
1578 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1579 return PLDM_ERROR_INVALID_LENGTH;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301580 }
1581
1582 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301583 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301584
Andrew Jeffery66c77232024-04-24 11:42:02 +09301585 pldm_msgbuf_extract_p(buf, sensor_id);
1586 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301587 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301588 return pldm_xlate_errno(rc);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301589 }
1590
1591 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301592 if (event_class_data_length !=
1593 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1594 return PLDM_ERROR_INVALID_LENGTH;
1595 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301596 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301597 if (event_class_data_length !=
1598 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1599 return PLDM_ERROR_INVALID_LENGTH;
1600 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301601 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301602 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301603 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301604 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301605 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301606 return PLDM_ERROR_INVALID_LENGTH;
1607 }
1608 } else {
1609 return PLDM_ERROR_INVALID_DATA;
1610 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301611
Andrew Jeffery9c766792022-08-10 23:12:49 +09301612 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301613 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301614
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301615 rc = pldm_msgbuf_destroy(buf);
1616 if (rc) {
1617 return pldm_xlate_errno(rc);
1618 }
1619
1620 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301621}
1622
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301623LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301624int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1625 uint8_t *present_op_state, uint8_t *previous_op_state)
1626{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301627 struct pldm_msgbuf _buf;
1628 struct pldm_msgbuf *buf = &_buf;
1629 int rc;
1630
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001631 if (sensor_data == NULL || present_op_state == NULL ||
1632 previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301633 return PLDM_ERROR_INVALID_DATA;
1634 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301635
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301636 rc = pldm_msgbuf_init_errno(
1637 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1638 sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301639 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301640 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301641 }
1642
Andrew Jeffery66c77232024-04-24 11:42:02 +09301643 pldm_msgbuf_extract_p(buf, present_op_state);
1644 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301645
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301646 rc = pldm_msgbuf_destroy_consumed(buf);
1647 if (rc) {
1648 return pldm_xlate_errno(rc);
1649 }
1650
1651 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301652}
1653
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301654LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301655int decode_state_sensor_data(const uint8_t *sensor_data,
1656 size_t sensor_data_length, uint8_t *sensor_offset,
1657 uint8_t *event_state,
1658 uint8_t *previous_event_state)
1659{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301660 struct pldm_msgbuf _buf;
1661 struct pldm_msgbuf *buf = &_buf;
1662 int rc;
1663
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001664 if (sensor_data == NULL || sensor_offset == NULL ||
1665 event_state == NULL || previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301666 return PLDM_ERROR_INVALID_DATA;
1667 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301668
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301669 rc = pldm_msgbuf_init_errno(
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301670 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1671 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301672 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301673 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301674 }
1675
Andrew Jeffery66c77232024-04-24 11:42:02 +09301676 pldm_msgbuf_extract_p(buf, sensor_offset);
1677 pldm_msgbuf_extract_p(buf, event_state);
1678 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301679
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301680 rc = pldm_msgbuf_destroy_consumed(buf);
1681 if (rc) {
1682 return pldm_xlate_errno(rc);
1683 }
1684
1685 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301686}
1687
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301688LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301689int decode_numeric_sensor_data(const uint8_t *sensor_data,
1690 size_t sensor_data_length, uint8_t *event_state,
1691 uint8_t *previous_event_state,
1692 uint8_t *sensor_data_size,
1693 uint32_t *present_reading)
1694{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301695 struct pldm_msgbuf _buf;
1696 struct pldm_msgbuf *buf = &_buf;
1697 int rc;
1698
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001699 if (sensor_data == NULL || sensor_data_size == NULL ||
1700 event_state == NULL || previous_event_state == NULL ||
1701 present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301702 return PLDM_ERROR_INVALID_DATA;
1703 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301704
1705 if (sensor_data_length >
1706 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301707 return PLDM_ERROR_INVALID_LENGTH;
1708 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301709
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301710 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301711 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1712 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301713 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301714 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301715 }
1716
Andrew Jeffery66c77232024-04-24 11:42:02 +09301717 pldm_msgbuf_extract_p(buf, event_state);
1718 pldm_msgbuf_extract_p(buf, previous_event_state);
1719 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301720 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301721 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301722 }
1723
1724 /*
1725 * The implementation below is bonkers, but it's because the function
1726 * prototype is bonkers. The `present_reading` argument should have been
1727 * a tagged union.
1728 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301729 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301730 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1731 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301732 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301733 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301734 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301735 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301736 }
1737 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1738 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301739 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301740 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301741 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301742 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301743 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301744 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301745 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301746 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301747 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301748 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301749 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301750 }
1751 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301752 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301753 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301754 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301755 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301756 break;
1757 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301758 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1759 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301760 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301761 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301762 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301763 break;
1764 }
1765 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1766 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301767 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301768 *present_reading = (uint32_t)val;
1769 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301770 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301771 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301772 default:
1773 return PLDM_ERROR_INVALID_DATA;
1774 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301775
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301776 rc = pldm_msgbuf_destroy_consumed(buf);
1777 if (rc) {
1778 return pldm_xlate_errno(rc);
1779 }
1780
1781 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301782}
1783
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301784LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301785int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301786 const void *pdr_data, size_t pdr_data_length,
1787 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301788{
1789 struct pldm_msgbuf _buf;
1790 struct pldm_msgbuf *buf = &_buf;
1791 int rc;
1792
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301793 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1794 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301795 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301796 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301797 }
1798
Andrew Jeffery329176a2024-09-26 22:38:24 +09301799 rc = pldm_msgbuf_extract_value_pdr_hdr(
1800 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301801 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301802 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09301803 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301804 }
1805
Andrew Jeffery66c77232024-04-24 11:42:02 +09301806 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1807 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1808 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1809 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1810 pldm_msgbuf_extract(buf, pdr_value->container_id);
1811 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1812 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1813 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1814 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1815 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1816 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1817 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1818 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1819 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1820 pldm_msgbuf_extract(buf, pdr_value->rel);
1821 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1822 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301823
Andrew Jeffery66c77232024-04-24 11:42:02 +09301824 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301825 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301826 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301827 }
1828 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1829 return PLDM_ERROR_INVALID_DATA;
1830 }
1831
Andrew Jeffery66c77232024-04-24 11:42:02 +09301832 pldm_msgbuf_extract(buf, pdr_value->resolution);
1833 pldm_msgbuf_extract(buf, pdr_value->offset);
1834 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1835 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1836 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301837 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1838 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301839 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301840 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301841 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1842 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1843 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301844 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1845 &pdr_value->max_readable);
1846 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1847 &pdr_value->min_readable);
1848
Andrew Jeffery66c77232024-04-24 11:42:02 +09301849 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301850 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301851 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301852 }
1853 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1854 return PLDM_ERROR_INVALID_DATA;
1855 }
1856
Andrew Jeffery66c77232024-04-24 11:42:02 +09301857 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301858 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301859 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301860 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301861 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301862 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301863 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301864 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301865 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301866 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301867 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301868 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301869 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301870 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301871 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301872 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301873 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301874 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301875 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301876
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301877 rc = pldm_msgbuf_destroy(buf);
1878 if (rc) {
1879 return pldm_xlate_errno(rc);
1880 }
1881
1882 return PLDM_SUCCESS;
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301883}
1884
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301885LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301886int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1887 uint16_t effecter_id,
1888 struct pldm_msg *msg)
1889{
1890 if (msg == NULL) {
1891 return PLDM_ERROR_INVALID_DATA;
1892 }
1893
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301894 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301895 header.msg_type = PLDM_REQUEST;
1896 header.instance = instance_id;
1897 header.pldm_type = PLDM_PLATFORM;
1898 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1899
1900 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1901 if (rc != PLDM_SUCCESS) {
1902 return rc;
1903 }
1904
1905 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301906 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301907 request->effecter_id = htole16(effecter_id);
1908
1909 return PLDM_SUCCESS;
1910}
1911
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301912LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301913int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301914 uint8_t instance_id, uint8_t completion_code,
1915 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1916 const uint8_t *pending_value, const uint8_t *present_value,
1917 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301918{
1919 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1920 return PLDM_ERROR_INVALID_DATA;
1921 }
1922
1923 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1924 return PLDM_ERROR_INVALID_DATA;
1925 }
1926
1927 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1928 return PLDM_ERROR_INVALID_DATA;
1929 }
1930
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301931 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301932 header.msg_type = PLDM_RESPONSE;
1933 header.instance = instance_id;
1934 header.pldm_type = PLDM_PLATFORM;
1935 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1936
1937 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1938 if (rc != PLDM_SUCCESS) {
1939 return rc;
1940 }
1941
1942 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301943 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301944
1945 response->completion_code = completion_code;
1946 response->effecter_data_size = effecter_data_size;
1947 response->effecter_oper_state = effecter_oper_state;
1948
1949 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1950 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1951 if (payload_length !=
1952 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1953 return PLDM_ERROR_INVALID_LENGTH;
1954 }
1955 response->pending_and_present_values[0] = *pending_value;
1956 response->pending_and_present_values[1] = *present_value;
1957
1958 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1959 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1960 if (payload_length !=
1961 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1962 return PLDM_ERROR_INVALID_LENGTH;
1963 }
1964 uint16_t val_pending = *(uint16_t *)pending_value;
1965 val_pending = htole16(val_pending);
1966 memcpy(response->pending_and_present_values, &val_pending,
1967 sizeof(uint16_t));
1968 uint16_t val_present = *(uint16_t *)present_value;
1969 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301970 memcpy((response->pending_and_present_values +
1971 sizeof(uint16_t)),
1972 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301973
1974 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1975 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1976 if (payload_length !=
1977 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1978 return PLDM_ERROR_INVALID_LENGTH;
1979 }
1980 uint32_t val_pending = *(uint32_t *)pending_value;
1981 val_pending = htole32(val_pending);
1982 memcpy(response->pending_and_present_values, &val_pending,
1983 sizeof(uint32_t));
1984 uint32_t val_present = *(uint32_t *)present_value;
1985 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301986 memcpy((response->pending_and_present_values +
1987 sizeof(uint32_t)),
1988 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301989 }
1990 return PLDM_SUCCESS;
1991}
1992
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301993LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301994int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1995 size_t payload_length,
1996 uint16_t *effecter_id)
1997{
Andrew Jefferydd265822023-04-13 22:42:44 +09301998 struct pldm_msgbuf _buf;
1999 struct pldm_msgbuf *buf = &_buf;
2000 int rc;
2001
Andrew Jeffery9c766792022-08-10 23:12:49 +09302002 if (msg == NULL || effecter_id == NULL) {
2003 return PLDM_ERROR_INVALID_DATA;
2004 }
2005
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302006 rc = pldm_msgbuf_init_errno(buf,
2007 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2008 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09302009 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302010 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302011 }
2012
Andrew Jeffery66c77232024-04-24 11:42:02 +09302013 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302014
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302015 rc = pldm_msgbuf_destroy_consumed(buf);
2016 if (rc) {
2017 return pldm_xlate_errno(rc);
2018 }
2019
2020 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302021}
2022
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302023LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302024int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2025 size_t payload_length,
2026 uint8_t *completion_code,
2027 uint8_t *effecter_data_size,
2028 uint8_t *effecter_oper_state,
2029 uint8_t *pending_value,
2030 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302031{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302032 struct pldm_msgbuf _buf;
2033 struct pldm_msgbuf *buf = &_buf;
2034 int rc;
2035
Andrew Jeffery9c766792022-08-10 23:12:49 +09302036 if (msg == NULL || effecter_data_size == NULL ||
2037 effecter_oper_state == NULL || pending_value == NULL ||
2038 present_value == NULL) {
2039 return PLDM_ERROR_INVALID_DATA;
2040 }
2041
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302042 rc = pldm_msgbuf_init_errno(
2043 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2044 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302045 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302046 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302047 }
2048
Andrew Jeffery66c77232024-04-24 11:42:02 +09302049 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302050 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302051 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302052 }
2053
Andrew Jeffery9c766792022-08-10 23:12:49 +09302054 if (PLDM_SUCCESS != *completion_code) {
2055 return PLDM_SUCCESS;
2056 }
2057
Andrew Jeffery66c77232024-04-24 11:42:02 +09302058 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302059 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302060 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302061 }
2062
Andrew Jeffery9c766792022-08-10 23:12:49 +09302063 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2064 return PLDM_ERROR_INVALID_DATA;
2065 }
2066
Andrew Jeffery66c77232024-04-24 11:42:02 +09302067 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302068 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302069 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302070 }
2071
Andrew Jeffery9c766792022-08-10 23:12:49 +09302072 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
2073 return PLDM_ERROR_INVALID_DATA;
2074 }
2075
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302076 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2077 pending_value);
2078 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2079 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302080
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302081 rc = pldm_msgbuf_destroy_consumed(buf);
2082 if (rc) {
2083 return pldm_xlate_errno(rc);
2084 }
2085
2086 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302087}
2088
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302089LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302090int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302091 uint8_t event_data_format, uint8_t number_of_change_records,
2092 const uint8_t *event_data_operations,
2093 const uint8_t *numbers_of_change_entries,
2094 const uint32_t *const *change_entries,
2095 struct pldm_pdr_repository_chg_event_data *event_data,
2096 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302097{
2098 if (event_data_operations == NULL ||
2099 numbers_of_change_entries == NULL || change_entries == NULL) {
2100 return PLDM_ERROR_INVALID_DATA;
2101 }
2102
2103 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302104 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302105
2106 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302107 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302108 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302109 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302110
2111 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302112 expected_size += sizeof(*change_entries[0]) *
2113 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302114 }
2115
2116 *actual_change_records_size = expected_size;
2117
2118 if (event_data == NULL) {
2119 return PLDM_SUCCESS;
2120 }
2121
2122 if (max_change_records_size < expected_size) {
2123 return PLDM_ERROR_INVALID_LENGTH;
2124 }
2125
2126 event_data->event_data_format = event_data_format;
2127 event_data->number_of_change_records = number_of_change_records;
2128
2129 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302130 (struct pldm_pdr_repository_change_record_data *)
2131 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302132
2133 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2134 record_data->event_data_operation = event_data_operations[i];
2135 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302136 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302137
2138 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2139 ++j) {
2140 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302141 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302142 }
2143
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302144 record_data =
2145 (struct pldm_pdr_repository_change_record_data
2146 *)(record_data->change_entry +
2147 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302148 }
2149
2150 return PLDM_SUCCESS;
2151}
2152
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302153LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302154int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2155 size_t event_data_size,
2156 uint8_t *event_data_format,
2157 uint8_t *number_of_change_records,
2158 size_t *change_record_data_offset)
2159{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302160 struct pldm_msgbuf _buf;
2161 struct pldm_msgbuf *buf = &_buf;
2162 int rc;
2163
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002164 if (event_data == NULL || event_data_format == NULL ||
2165 number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302166 change_record_data_offset == NULL) {
2167 return PLDM_ERROR_INVALID_DATA;
2168 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302169
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302170 rc = pldm_msgbuf_init_errno(buf,
2171 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2172 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302173 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302174 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302175 }
2176
Andrew Jeffery66c77232024-04-24 11:42:02 +09302177 pldm_msgbuf_extract_p(buf, event_data_format);
2178 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302179
Andrew Jeffery9c766792022-08-10 23:12:49 +09302180 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302181 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302182
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302183 rc = pldm_msgbuf_destroy(buf);
2184 if (rc) {
2185 return pldm_xlate_errno(rc);
2186 }
2187
2188 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302189}
2190
Thu Nguyenf874b382024-07-24 11:22:34 +00002191LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00002192int decode_pldm_message_poll_event_data(
2193 const void *event_data, size_t event_data_length,
2194 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07002195{
2196 struct pldm_msgbuf _buf;
2197 struct pldm_msgbuf *buf = &_buf;
2198 int rc;
2199
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002200 if (!event_data || !poll_event) {
Thu Nguyen7739d122024-07-26 11:36:39 +00002201 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07002202 }
2203
Thu Nguyen7739d122024-07-26 11:36:39 +00002204 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2205 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002206 if (rc) {
2207 return rc;
2208 }
2209
Thu Nguyen7739d122024-07-26 11:36:39 +00002210 pldm_msgbuf_extract(buf, poll_event->format_version);
2211 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07002212 if (rc) {
2213 return rc;
2214 }
2215
Thu Nguyen7739d122024-07-26 11:36:39 +00002216 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2217 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002218 }
2219
Thu Nguyen7739d122024-07-26 11:36:39 +00002220 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002221
2222 return pldm_msgbuf_destroy_consumed(buf);
2223}
2224
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302225LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00002226int encode_pldm_message_poll_event_data(
2227 const struct pldm_message_poll_event *poll_event, void *event_data,
2228 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07002229{
2230 struct pldm_msgbuf _buf;
2231 struct pldm_msgbuf *buf = &_buf;
2232 int rc;
2233
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002234 if (poll_event == NULL || event_data == NULL) {
2235 return -EINVAL;
2236 }
2237
Thu Nguyen7739d122024-07-26 11:36:39 +00002238 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2239 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002240 }
2241
Thu Nguyen7739d122024-07-26 11:36:39 +00002242 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2243 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002244 if (rc) {
2245 return rc;
2246 }
Thu Nguyen7739d122024-07-26 11:36:39 +00002247 pldm_msgbuf_insert(buf, poll_event->format_version);
2248 pldm_msgbuf_insert(buf, poll_event->event_id);
2249 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002250
Thu Nguyen7739d122024-07-26 11:36:39 +00002251 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002252}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302253
2254LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302255int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302256 const uint8_t *change_record_data, size_t change_record_data_size,
2257 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
2258 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302259{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302260 struct pldm_msgbuf _buf;
2261 struct pldm_msgbuf *buf = &_buf;
2262 int rc;
2263
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002264 if (change_record_data == NULL || event_data_operation == NULL ||
2265 number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302266 change_entry_data_offset == NULL) {
2267 return PLDM_ERROR_INVALID_DATA;
2268 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302269
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302270 rc = pldm_msgbuf_init_errno(
2271 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2272 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302273 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302274 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302275 }
2276
Andrew Jeffery66c77232024-04-24 11:42:02 +09302277 pldm_msgbuf_extract_p(buf, event_data_operation);
2278 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302279
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302280 *change_entry_data_offset = sizeof(*event_data_operation) +
2281 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302282
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302283 rc = pldm_msgbuf_destroy(buf);
2284 if (rc) {
2285 return pldm_xlate_errno(rc);
2286 }
2287
2288 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302289}
2290
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302291LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302292int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2293 uint8_t rearm_event_state,
2294 struct pldm_msg *msg)
2295{
2296 if (msg == NULL) {
2297 return PLDM_ERROR_INVALID_DATA;
2298 }
2299
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302300 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302301 header.msg_type = PLDM_REQUEST;
2302 header.instance = instance_id;
2303 header.pldm_type = PLDM_PLATFORM;
2304 header.command = PLDM_GET_SENSOR_READING;
2305
2306 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2307 if (rc != PLDM_SUCCESS) {
2308 return rc;
2309 }
2310
2311 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302312 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302313
2314 request->sensor_id = htole16(sensor_id);
2315 request->rearm_event_state = rearm_event_state;
2316
2317 return PLDM_SUCCESS;
2318}
2319
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302320LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302321int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302322 const struct pldm_msg *msg, size_t payload_length,
2323 uint8_t *completion_code, uint8_t *sensor_data_size,
2324 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2325 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2326 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302327{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302328 struct pldm_msgbuf _buf;
2329 struct pldm_msgbuf *buf = &_buf;
2330 int rc;
2331
Andrew Jeffery9c766792022-08-10 23:12:49 +09302332 if (msg == NULL || completion_code == NULL ||
2333 sensor_data_size == NULL || sensor_operational_state == NULL ||
2334 sensor_event_message_enable == NULL || present_state == NULL ||
2335 previous_state == NULL || event_state == NULL ||
2336 present_reading == NULL) {
2337 return PLDM_ERROR_INVALID_DATA;
2338 }
2339
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302340 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2341 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302342 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302343 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302344 }
2345
Andrew Jeffery66c77232024-04-24 11:42:02 +09302346 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302347 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302348 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302349 }
2350
Andrew Jeffery9c766792022-08-10 23:12:49 +09302351 if (PLDM_SUCCESS != *completion_code) {
2352 return PLDM_SUCCESS;
2353 }
2354
Andrew Jeffery66c77232024-04-24 11:42:02 +09302355 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302356 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302357 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302358 }
2359
Andrew Jeffery840b1402023-04-13 23:54:44 +09302360 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302361 return PLDM_ERROR_INVALID_DATA;
2362 }
2363
Andrew Jeffery66c77232024-04-24 11:42:02 +09302364 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2365 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2366 pldm_msgbuf_extract_p(buf, present_state);
2367 pldm_msgbuf_extract_p(buf, previous_state);
2368 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302369
Andrew Jeffery840b1402023-04-13 23:54:44 +09302370 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2371 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302372
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302373 rc = pldm_msgbuf_destroy_consumed(buf);
2374 if (rc) {
2375 return pldm_xlate_errno(rc);
2376 }
2377
2378 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302379}
2380
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302381LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302382int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2383 uint8_t sensor_data_size,
2384 uint8_t sensor_operational_state,
2385 uint8_t sensor_event_message_enable,
2386 uint8_t present_state,
2387 uint8_t previous_state, uint8_t event_state,
2388 const uint8_t *present_reading,
2389 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302390{
2391 if (msg == NULL || present_reading == NULL) {
2392 return PLDM_ERROR_INVALID_DATA;
2393 }
2394
2395 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2396 return PLDM_ERROR_INVALID_DATA;
2397 }
2398
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302399 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302400 header.msg_type = PLDM_RESPONSE;
2401 header.instance = instance_id;
2402 header.pldm_type = PLDM_PLATFORM;
2403 header.command = PLDM_GET_SENSOR_READING;
2404
2405 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2406 if (rc != PLDM_SUCCESS) {
2407 return rc;
2408 }
2409
2410 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302411 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302412
2413 response->completion_code = completion_code;
2414 response->sensor_data_size = sensor_data_size;
2415 response->sensor_operational_state = sensor_operational_state;
2416 response->sensor_event_message_enable = sensor_event_message_enable;
2417 response->present_state = present_state;
2418 response->previous_state = previous_state;
2419 response->event_state = event_state;
2420
2421 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2422 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2423 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2424 return PLDM_ERROR_INVALID_LENGTH;
2425 }
2426 response->present_reading[0] = *present_reading;
2427
2428 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2429 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2430 if (payload_length !=
2431 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2432 return PLDM_ERROR_INVALID_LENGTH;
2433 }
2434 uint16_t val = *(uint16_t *)present_reading;
2435 val = htole16(val);
2436 memcpy(response->present_reading, &val, 2);
2437
2438 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2439 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2440 if (payload_length !=
2441 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2442 return PLDM_ERROR_INVALID_LENGTH;
2443 }
2444 uint32_t val = *(uint32_t *)present_reading;
2445 val = htole32(val);
2446 memcpy(response->present_reading, &val, 4);
2447 }
2448
2449 return PLDM_SUCCESS;
2450}
2451
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302452LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302453int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2454 size_t payload_length, uint16_t *sensor_id,
2455 uint8_t *rearm_event_state)
2456{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302457 struct pldm_msgbuf _buf;
2458 struct pldm_msgbuf *buf = &_buf;
2459 int rc;
2460
Andrew Jeffery9c766792022-08-10 23:12:49 +09302461 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2462 return PLDM_ERROR_INVALID_DATA;
2463 }
2464
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302465 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2466 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302467 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302468 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302469 }
2470
Andrew Jeffery66c77232024-04-24 11:42:02 +09302471 pldm_msgbuf_extract_p(buf, sensor_id);
2472 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302473
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302474 rc = pldm_msgbuf_destroy(buf);
2475 if (rc) {
2476 return pldm_xlate_errno(rc);
2477 }
2478
2479 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302480}
2481
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302482LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302483int encode_set_event_receiver_req(uint8_t instance_id,
2484 uint8_t event_message_global_enable,
2485 uint8_t transport_protocol_type,
2486 uint8_t event_receiver_address_info,
2487 uint16_t heartbeat_timer,
2488 struct pldm_msg *msg)
2489{
2490 if (msg == NULL) {
2491 return PLDM_ERROR_INVALID_DATA;
2492 }
2493
2494 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2495 return PLDM_ERROR_INVALID_DATA;
2496 }
2497
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302498 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302499 header.msg_type = PLDM_REQUEST;
2500 header.instance = instance_id;
2501 header.pldm_type = PLDM_PLATFORM;
2502 header.command = PLDM_SET_EVENT_RECEIVER;
2503
2504 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2505 if (rc != PLDM_SUCCESS) {
2506 return rc;
2507 }
2508
2509 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302510 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302511 request->event_message_global_enable = event_message_global_enable;
2512
2513 request->transport_protocol_type = transport_protocol_type;
2514 request->event_receiver_address_info = event_receiver_address_info;
2515
2516 if (event_message_global_enable ==
2517 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2518 if (heartbeat_timer == 0) {
2519 return PLDM_ERROR_INVALID_DATA;
2520 }
2521 request->heartbeat_timer = htole16(heartbeat_timer);
2522 }
2523
2524 return PLDM_SUCCESS;
2525}
2526
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302527LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302528int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2529 size_t payload_length,
2530 uint8_t *completion_code)
2531{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302532 struct pldm_msgbuf _buf;
2533 struct pldm_msgbuf *buf = &_buf;
2534 int rc;
2535
Andrew Jeffery9c766792022-08-10 23:12:49 +09302536 if (msg == NULL || completion_code == NULL) {
2537 return PLDM_ERROR_INVALID_DATA;
2538 }
2539
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302540 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2541 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302542 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302543 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302544 }
2545
Andrew Jeffery66c77232024-04-24 11:42:02 +09302546 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302547
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302548 rc = pldm_msgbuf_destroy(buf);
2549 if (rc) {
2550 return pldm_xlate_errno(rc);
2551 }
2552
2553 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302554}
2555
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302556LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302557int decode_set_event_receiver_req(const struct pldm_msg *msg,
2558 size_t payload_length,
2559 uint8_t *event_message_global_enable,
2560 uint8_t *transport_protocol_type,
2561 uint8_t *event_receiver_address_info,
2562 uint16_t *heartbeat_timer)
2563
2564{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302565 struct pldm_msgbuf _buf;
2566 struct pldm_msgbuf *buf = &_buf;
2567 int rc;
2568
Andrew Jeffery9c766792022-08-10 23:12:49 +09302569 if (msg == NULL || event_message_global_enable == NULL ||
2570 transport_protocol_type == NULL ||
2571 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2572 return PLDM_ERROR_INVALID_DATA;
2573 }
2574
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302575 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2576 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302577 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302578 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302579 }
2580
Andrew Jeffery66c77232024-04-24 11:42:02 +09302581 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2582 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2583 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
Andrew Jeffery2332e052024-10-08 13:52:34 +10302584 pldm_msgbuf_extract_p(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302585
Andrew Jeffery9667f582023-04-14 00:39:21 +09302586 rc = pldm_msgbuf_destroy(buf);
2587 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302588 return pldm_xlate_errno(rc);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302589 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302590
Andrew Jeffery9c766792022-08-10 23:12:49 +09302591 if ((*event_message_global_enable ==
2592 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2593 (*heartbeat_timer == 0)) {
2594 return PLDM_ERROR_INVALID_DATA;
2595 }
2596
Andrew Jeffery9c766792022-08-10 23:12:49 +09302597 return PLDM_SUCCESS;
2598}
2599
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302600LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302601int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2602 struct pldm_msg *msg)
2603
2604{
2605 if (msg == NULL) {
2606 return PLDM_ERROR_INVALID_DATA;
2607 }
2608
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302609 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302610 header.instance = instance_id;
2611 header.msg_type = PLDM_RESPONSE;
2612 header.pldm_type = PLDM_PLATFORM;
2613 header.command = PLDM_SET_EVENT_RECEIVER;
2614
2615 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2616 if (rc != PLDM_SUCCESS) {
2617 return rc;
2618 }
2619
2620 msg->payload[0] = completion_code;
2621
2622 return PLDM_SUCCESS;
2623}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002624
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302625LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002626int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2627 uint8_t format_version,
2628 uint8_t transfer_operation_flag,
2629 uint32_t data_transfer_handle,
2630 uint16_t event_id_to_acknowledge,
2631 struct pldm_msg *msg,
2632 size_t payload_length)
2633{
2634 struct pldm_msgbuf _buf;
2635 struct pldm_msgbuf *buf = &_buf;
2636 int rc;
2637
2638 if (msg == NULL) {
2639 return PLDM_ERROR_INVALID_DATA;
2640 }
2641
Thu Nguyen387b10f2024-09-24 11:33:16 +00002642 rc = pldm_platform_poll_for_platform_event_message_validate(
2643 transfer_operation_flag, event_id_to_acknowledge);
2644 if (rc < 0) {
2645 return PLDM_ERROR_INVALID_DATA;
2646 }
2647
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302648 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002649 header.msg_type = PLDM_REQUEST;
2650 header.instance = instance_id;
2651 header.pldm_type = PLDM_PLATFORM;
2652 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2653
2654 rc = pack_pldm_header(&header, &(msg->hdr));
2655 if (rc != PLDM_SUCCESS) {
2656 return rc;
2657 }
2658
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302659 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302660 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2661 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002662 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302663 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002664 }
2665
2666 pldm_msgbuf_insert(buf, format_version);
2667 pldm_msgbuf_insert(buf, transfer_operation_flag);
2668 pldm_msgbuf_insert(buf, data_transfer_handle);
2669 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2670
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302671 rc = pldm_msgbuf_destroy(buf);
2672 if (rc) {
2673 return pldm_xlate_errno(rc);
2674 }
2675
2676 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002677}
2678
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302679LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002680int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302681 const struct pldm_msg *msg, size_t payload_length,
2682 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2683 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2684 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2685 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002686{
2687 struct pldm_msgbuf _buf;
2688 struct pldm_msgbuf *buf = &_buf;
2689 int rc;
2690
2691 if (msg == NULL || completion_code == NULL || tid == NULL ||
2692 event_id == NULL || next_data_transfer_handle == NULL ||
2693 transfer_flag == NULL || event_class == NULL ||
2694 event_data_size == NULL || event_data == NULL ||
2695 event_data_integrity_checksum == NULL) {
2696 return PLDM_ERROR_INVALID_DATA;
2697 }
2698
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302699 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302700 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2701 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002702 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302703 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002704 }
2705
Andrew Jeffery66c77232024-04-24 11:42:02 +09302706 rc = pldm_msgbuf_extract_p(buf, completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002707 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302708 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002709 }
2710 if (PLDM_SUCCESS != *completion_code) {
2711 return *completion_code;
2712 }
2713
Andrew Jeffery66c77232024-04-24 11:42:02 +09302714 pldm_msgbuf_extract_p(buf, tid);
2715 rc = pldm_msgbuf_extract_p(buf, event_id);
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 ((*event_id == 0) || (*event_id == 0xffff)) {
2720 return PLDM_SUCCESS;
2721 }
2722
Andrew Jeffery66c77232024-04-24 11:42:02 +09302723 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2724 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
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
Andrew Jeffery66c77232024-04-24 11:42:02 +09302729 pldm_msgbuf_extract_p(buf, event_class);
2730 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002731 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302732 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002733 }
2734 if (*event_data_size > payload_length) {
2735 return PLDM_ERROR_INVALID_DATA;
2736 }
2737
2738 if (*event_data_size > 0) {
2739 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2740 }
2741
2742 if (*transfer_flag == PLDM_END ||
2743 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302744 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002745 }
2746
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302747 rc = pldm_msgbuf_destroy_consumed(buf);
2748 if (rc) {
2749 return pldm_xlate_errno(rc);
2750 }
2751
2752 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002753}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002754
2755LIBPLDM_ABI_TESTING
2756int decode_numeric_effecter_pdr_data(
2757 const void *pdr_data, size_t pdr_data_length,
2758 struct pldm_numeric_effecter_value_pdr *pdr_value)
2759{
2760 struct pldm_msgbuf _buf;
2761 struct pldm_msgbuf *buf = &_buf;
2762 struct pldm_value_pdr_hdr hdr;
2763 int rc;
2764
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002765 if (!pdr_data || !pdr_value) {
2766 return PLDM_ERROR_INVALID_DATA;
2767 }
2768
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302769 rc = pldm_msgbuf_init_errno(buf,
2770 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2771 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002772 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302773 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002774 }
2775
Andrew Jeffery329176a2024-09-26 22:38:24 +09302776 rc = pldm_msgbuf_extract_value_pdr_hdr(
2777 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
Thu Nguyend4878cd2023-11-09 10:18:33 +07002778 pdr_data_length);
2779 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09302780 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002781 }
2782
2783 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2784
2785 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2786 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2787 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2788 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2789 pldm_msgbuf_extract(buf, pdr_value->container_id);
2790 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2791 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2792 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2793 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2794 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2795 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2796 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2797 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2798 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2799 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2800 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2801 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2802
2803 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2804 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302805 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002806 }
2807 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2808 return PLDM_ERROR_INVALID_DATA;
2809 }
2810
2811 pldm_msgbuf_extract(buf, pdr_value->resolution);
2812 pldm_msgbuf_extract(buf, pdr_value->offset);
2813 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2814 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2815 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2816 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2817 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2818 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2819 pdr_value->max_settable);
2820 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2821 pdr_value->min_settable);
2822
2823 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2824 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302825 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002826 }
2827 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2828 return PLDM_ERROR_INVALID_DATA;
2829 }
2830
2831 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2832 pldm_msgbuf_extract_range_field_format(
2833 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2834 pldm_msgbuf_extract_range_field_format(
2835 buf, pdr_value->range_field_format, pdr_value->normal_max);
2836 pldm_msgbuf_extract_range_field_format(
2837 buf, pdr_value->range_field_format, pdr_value->normal_min);
2838 pldm_msgbuf_extract_range_field_format(
2839 buf, pdr_value->range_field_format, pdr_value->rated_max);
2840 pldm_msgbuf_extract_range_field_format(
2841 buf, pdr_value->range_field_format, pdr_value->rated_min);
2842
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302843 rc = pldm_msgbuf_destroy_consumed(buf);
2844 if (rc) {
2845 return pldm_xlate_errno(rc);
2846 }
2847
2848 return PLDM_SUCCESS;
Thu Nguyend4878cd2023-11-09 10:18:33 +07002849}
Tal Yacobia6fa5552024-05-05 16:57:38 +03002850
Tal Yacobide67ab62024-05-30 22:36:50 +03002851LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002852int encode_get_state_effecter_states_req(uint8_t instance_id,
2853 uint16_t effecter_id,
2854 struct pldm_msg *msg,
2855 size_t payload_length)
2856{
2857 struct pldm_msgbuf _buf;
2858 struct pldm_msgbuf *buf = &_buf;
2859 int rc;
2860
2861 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002862 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002863 }
2864
2865 struct pldm_header_info header = { 0 };
2866 header.msg_type = PLDM_REQUEST;
2867 header.instance = instance_id;
2868 header.pldm_type = PLDM_PLATFORM;
2869 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2870
Tal Yacobif490a382024-05-31 09:57:36 +03002871 rc = pack_pldm_header_errno(&header, &msg->hdr);
2872 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002873 return rc;
2874 }
2875
Tal Yacobif490a382024-05-31 09:57:36 +03002876 rc = pldm_msgbuf_init_errno(buf,
2877 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2878 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002879 if (rc) {
2880 return rc;
2881 }
2882
2883 pldm_msgbuf_insert(buf, effecter_id);
2884
2885 return pldm_msgbuf_destroy_consumed(buf);
2886}
2887
Tal Yacobide67ab62024-05-30 22:36:50 +03002888LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002889int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
2890 size_t payload_length,
2891 uint16_t *effecter_id)
2892{
2893 struct pldm_msgbuf _buf;
2894 struct pldm_msgbuf *buf = &_buf;
2895 int rc;
2896
2897 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002898 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002899 }
2900
Tal Yacobif490a382024-05-31 09:57:36 +03002901 rc = pldm_msgbuf_init_errno(
2902 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2903 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002904 if (rc) {
2905 return rc;
2906 }
2907
2908 pldm_msgbuf_extract_p(buf, effecter_id);
2909
2910 return pldm_msgbuf_destroy_consumed(buf);
2911}
2912
Tal Yacobide67ab62024-05-30 22:36:50 +03002913LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002914int decode_get_state_effecter_states_resp(
2915 const struct pldm_msg *msg, size_t payload_length,
2916 struct pldm_get_state_effecter_states_resp *resp)
2917{
2918 struct pldm_msgbuf _buf;
2919 struct pldm_msgbuf *buf = &_buf;
2920 get_effecter_state_field *field;
2921 int rc;
2922 int i;
2923
2924 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002925 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002926 }
2927
Tal Yacobif490a382024-05-31 09:57:36 +03002928 rc = pldm_msgbuf_init_errno(
2929 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2930 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002931 if (rc) {
2932 return rc;
2933 }
2934
2935 rc = pldm_msgbuf_extract(buf, resp->completion_code);
2936 if (rc) {
2937 return rc;
2938 }
2939
2940 if (PLDM_SUCCESS != resp->completion_code) {
Tal Yacobif490a382024-05-31 09:57:36 +03002941 return 0;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002942 }
2943
2944 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
2945 if (rc) {
2946 return rc;
2947 }
2948
2949 uint8_t comp_effecter_count = resp->comp_effecter_count;
2950
2951 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2952 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002953 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002954 }
2955
2956 for (i = 0, field = resp->field; i < comp_effecter_count;
2957 i++, field++) {
2958 pldm_msgbuf_extract(buf, field->effecter_op_state);
2959 pldm_msgbuf_extract(buf, field->pending_state);
2960 pldm_msgbuf_extract(buf, field->present_state);
2961 }
2962
2963 return pldm_msgbuf_destroy_consumed(buf);
2964}
2965
Tal Yacobide67ab62024-05-30 22:36:50 +03002966LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002967int encode_get_state_effecter_states_resp(
2968 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
2969 struct pldm_msg *msg, size_t payload_length)
2970{
2971 struct pldm_msgbuf _buf;
2972 struct pldm_msgbuf *buf = &_buf;
2973 get_effecter_state_field *field;
2974 int rc;
2975 int i;
2976
2977 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002978 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002979 }
2980
2981 uint8_t comp_effecter_count = resp->comp_effecter_count;
2982
2983 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2984 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002985 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002986 }
2987
2988 struct pldm_header_info header = { 0 };
2989 header.msg_type = PLDM_RESPONSE;
2990 header.instance = instance_id;
2991 header.pldm_type = PLDM_PLATFORM;
2992 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2993
Tal Yacobif490a382024-05-31 09:57:36 +03002994 rc = pack_pldm_header_errno(&header, &msg->hdr);
2995 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002996 return rc;
2997 }
2998
Tal Yacobif490a382024-05-31 09:57:36 +03002999 rc = pldm_msgbuf_init_errno(
3000 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3001 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003002 if (rc) {
3003 return rc;
3004 }
3005
3006 pldm_msgbuf_insert(buf, resp->completion_code);
3007 pldm_msgbuf_insert(buf, comp_effecter_count);
3008
3009 for (i = 0, field = resp->field; i < comp_effecter_count;
3010 i++, field++) {
3011 pldm_msgbuf_insert(buf, field->effecter_op_state);
3012 pldm_msgbuf_insert(buf, field->pending_state);
3013 pldm_msgbuf_insert(buf, field->present_state);
3014 }
3015
3016 return pldm_msgbuf_destroy_consumed(buf);
3017}
Thu Nguyendacfa352024-06-22 09:53:15 +00003018
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003019LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003020int decode_entity_auxiliary_names_pdr(
3021 const void *data, size_t data_length,
3022 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3023{
3024 struct pldm_msgbuf _buf;
3025 struct pldm_msgbuf *buf = &_buf;
3026 struct pldm_msgbuf _src;
3027 struct pldm_msgbuf *src = &_src;
3028 struct pldm_msgbuf _dst;
3029 struct pldm_msgbuf *dst = &_dst;
3030 size_t names_len = 0;
3031 void *names = NULL;
3032 int rc;
3033 int i;
3034
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003035 if (!data || !pdr) {
3036 return -EINVAL;
3037 }
3038
Thu Nguyendacfa352024-06-22 09:53:15 +00003039 /*
3040 * Alignment of auxiliary_name_data is an invariant as we statically assert
3041 * its behaviour in the header.
3042 */
3043 assert(!((uintptr_t)pdr->auxiliary_name_data &
3044 (alignof(pldm_utf16be) - 1)));
3045
3046 /* Reject any lengths that are obviously invalid */
3047 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3048 return -EINVAL;
3049 }
3050
3051 rc = pldm_msgbuf_init_errno(
3052 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3053 data_length);
3054 if (rc) {
3055 return rc;
3056 }
3057
Andrew Jeffery329176a2024-09-26 22:38:24 +09303058 rc = pldm_msgbuf_extract_value_pdr_hdr(
3059 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
Thu Nguyendacfa352024-06-22 09:53:15 +00003060 data_length);
3061 if (rc) {
3062 return rc;
3063 }
3064
3065 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3066 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3067 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3068 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3069 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3070 if (rc < 0) {
3071 return rc;
3072 }
3073
3074 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3075 if (rc < 0) {
3076 return rc;
3077 }
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003078 assert(names);
Thu Nguyendacfa352024-06-22 09:53:15 +00003079
3080 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3081
3082 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3083 pdr->auxiliary_name_data,
3084 pdr->auxiliary_name_data_size);
3085 if (rc < 0) {
3086 return rc;
3087 }
3088
3089 /*
3090 * Below we do two passes over the same region. This is to first pack the
3091 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3092 * to maintain appropriate alignment.
3093 */
3094
3095 /* Initialise for the first pass to extract the UTF16-BE name strings */
3096 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3097 if (rc < 0) {
3098 return rc;
3099 }
3100
3101 for (i = 0; i < pdr->name_string_count; i++) {
3102 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003103 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3104 if (rc) {
3105 return rc;
3106 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003107 }
3108
3109 rc = pldm_msgbuf_destroy_consumed(src);
3110 if (rc < 0) {
3111 return rc;
3112 }
3113
3114 /* Reinitialise for the second pass to extract the ASCII tag strings */
3115 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3116 if (rc < 0) {
3117 return rc;
3118 }
3119
3120 for (i = 0; i < pdr->name_string_count; i++) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003121 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3122 if (rc) {
3123 return rc;
3124 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003125 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3126 }
3127
3128 if ((rc = pldm_msgbuf_destroy(dst)) ||
3129 (rc = pldm_msgbuf_destroy(src)) ||
3130 (rc = pldm_msgbuf_destroy(buf))) {
3131 return rc;
3132 }
3133
3134 return 0;
3135}
3136
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003137LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003138int decode_pldm_entity_auxiliary_names_pdr_index(
3139 struct pldm_entity_auxiliary_names_pdr *pdr)
3140{
3141 struct pldm_msgbuf _buf;
3142 struct pldm_msgbuf *buf = &_buf;
3143 int rc;
3144 int i;
3145
3146 if (!pdr) {
3147 return -EINVAL;
3148 }
3149
3150 if (pdr->name_string_count == 0 && pdr->names) {
3151 return -EINVAL;
3152 }
3153
3154 if (pdr->name_string_count > 0 && !pdr->names) {
3155 return -EINVAL;
3156 }
3157
3158 if (pdr->name_string_count == 0) {
3159 return 0;
3160 }
3161
3162 /*
3163 * Minimum size is one NUL for each member of each entry
3164 *
3165 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3166 * states the following:
3167 *
3168 * > A null-terminated ISO646 ASCII string ...
3169 * >
3170 * > special value: null string = 0x0000 = unspecified.
3171 *
3172 * Until proven otherwise we will assume the "0x0000" is a
3173 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3174 * represented by a single byte.
3175 */
3176 rc = pldm_msgbuf_init_errno(
3177 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3178 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3179 if (rc) {
3180 return rc;
3181 }
3182
3183 for (i = 0; i < pdr->name_string_count; i++) {
3184 void *loc = NULL;
3185 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3186 pdr->names[i].name = loc;
3187 }
3188
3189 for (i = 0; i < pdr->name_string_count; i++) {
3190 void *loc = NULL;
3191 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3192 pdr->names[i].tag = loc;
3193 }
3194
3195 return pldm_msgbuf_destroy_consumed(buf);
3196}
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003197
Thu Nguyen3559aa12024-08-29 00:13:38 +00003198LIBPLDM_ABI_STABLE
Thu Nguyen02903032024-09-03 06:39:50 +00003199int decode_pldm_platform_cper_event(const void *event_data,
3200 size_t event_data_length,
3201 struct pldm_platform_cper_event *cper_event,
3202 size_t cper_event_length)
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003203{
3204 struct pldm_msgbuf _buf;
3205 struct pldm_msgbuf *buf = &_buf;
3206 int rc;
3207
3208 if (!cper_event || !event_data) {
3209 return -EINVAL;
3210 }
3211
3212 if (cper_event_length < sizeof(*cper_event)) {
3213 return -EINVAL;
3214 }
3215
3216 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3217 event_data, event_data_length);
3218 if (rc) {
3219 return rc;
3220 }
3221
3222 pldm_msgbuf_extract(buf, cper_event->format_version);
3223 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3224 if (rc) {
3225 return rc;
3226 }
3227 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3228 cper_event->format_type !=
3229 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3230 return -EPROTO;
3231 }
3232
3233 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3234 if (rc) {
3235 return rc;
3236 }
3237
3238 if (cper_event->event_data_length >
3239 (cper_event_length - sizeof(*cper_event))) {
3240 return -EOVERFLOW;
3241 }
3242
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003243 rc = pldm_msgbuf_extract_array_uint8(
3244 buf, cper_event->event_data_length, cper_event->event_data,
3245 cper_event_length - sizeof(*cper_event));
3246 if (rc) {
3247 return rc;
3248 }
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003249
3250 return pldm_msgbuf_destroy_consumed(buf);
3251}
3252
Thu Nguyen3559aa12024-08-29 00:13:38 +00003253LIBPLDM_ABI_STABLE
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003254uint8_t *
3255pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3256{
3257 return event->event_data;
3258}