blob: 7cf5853f923f3efa35a275ee54fde9a19a6018d2 [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
1299 if (payload_length !=
1300 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1301 return PLDM_ERROR_INVALID_LENGTH;
1302 }
1303
John Chungb43a7782024-09-26 22:04:27 +08001304 if (event_class > PLDM_CPER_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001305 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301306 return PLDM_ERROR_INVALID_DATA;
1307 }
1308
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301309 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301310 header.msg_type = PLDM_REQUEST;
1311 header.instance = instance_id;
1312 header.pldm_type = PLDM_PLATFORM;
1313 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1314
1315 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1316 if (rc != PLDM_SUCCESS) {
1317 return rc;
1318 }
1319
1320 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301321 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301322 request->format_version = format_version;
1323 request->tid = tid;
1324 request->event_class = event_class;
1325 memcpy(request->event_data, event_data, event_data_length);
1326
1327 return PLDM_SUCCESS;
1328}
1329
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301330LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301331int decode_platform_event_message_resp(const struct pldm_msg *msg,
1332 size_t payload_length,
1333 uint8_t *completion_code,
1334 uint8_t *platform_event_status)
1335{
Andrew Jefferye5011772023-04-13 12:06:22 +09301336 struct pldm_msgbuf _buf;
1337 struct pldm_msgbuf *buf = &_buf;
1338 int rc;
1339
Andrew Jeffery9c766792022-08-10 23:12:49 +09301340 if (msg == NULL || completion_code == NULL ||
1341 platform_event_status == NULL) {
1342 return PLDM_ERROR_INVALID_DATA;
1343 }
1344
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301345 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1346 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301347 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301348 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301349 }
1350
Andrew Jeffery66c77232024-04-24 11:42:02 +09301351 rc = pldm_msgbuf_extract_p(buf, completion_code);
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 Jeffery9c766792022-08-10 23:12:49 +09301356 if (PLDM_SUCCESS != *completion_code) {
1357 return PLDM_SUCCESS;
1358 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301359
Andrew Jeffery66c77232024-04-24 11:42:02 +09301360 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301361 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301362 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301363 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301364
1365 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1366 return PLDM_ERROR_INVALID_DATA;
1367 }
1368
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301369 rc = pldm_msgbuf_destroy(buf);
1370 if (rc) {
1371 return pldm_xlate_errno(rc);
1372 }
1373
1374 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301375}
1376
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301377LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301378int encode_event_message_buffer_size_req(uint8_t instance_id,
1379 uint16_t event_receiver_max_buffer_size,
1380 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001381{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301382 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001383 header.msg_type = PLDM_REQUEST;
1384 header.instance = instance_id;
1385 header.pldm_type = PLDM_PLATFORM;
1386 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1387
1388 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1389 if (rc != PLDM_SUCCESS) {
1390 return rc;
1391 }
1392
1393 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301394 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001395 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301396 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001397
1398 return PLDM_SUCCESS;
1399}
1400
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301401LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001402int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1403 size_t payload_length,
1404 uint8_t *completion_code,
1405 uint16_t *terminus_max_buffer_size)
1406{
Andrew Jeffery11126902023-04-13 12:12:10 +09301407 struct pldm_msgbuf _buf;
1408 struct pldm_msgbuf *buf = &_buf;
1409 int rc;
1410
Dung Caod6ae8982022-11-02 10:00:10 +07001411 if (msg == NULL || completion_code == NULL ||
1412 terminus_max_buffer_size == NULL) {
1413 return PLDM_ERROR_INVALID_DATA;
1414 }
1415
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301416 rc = pldm_msgbuf_init_errno(buf,
1417 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1418 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301419 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301420 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301421 }
1422
Andrew Jeffery66c77232024-04-24 11:42:02 +09301423 rc = pldm_msgbuf_extract_p(buf, completion_code);
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
Dung Caod6ae8982022-11-02 10:00:10 +07001428 if (PLDM_SUCCESS != *completion_code) {
1429 return PLDM_SUCCESS;
1430 }
Dung Caod6ae8982022-11-02 10:00:10 +07001431
Andrew Jeffery66c77232024-04-24 11:42:02 +09301432 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001433
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301434 rc = pldm_msgbuf_destroy_consumed(buf);
1435 if (rc) {
1436 return pldm_xlate_errno(rc);
1437 }
1438
1439 return PLDM_SUCCESS;
Dung Caod6ae8982022-11-02 10:00:10 +07001440}
1441
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301442LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001443int encode_event_message_supported_req(uint8_t instance_id,
1444 uint8_t format_version,
1445 struct pldm_msg *msg)
1446{
1447 if (format_version != 1) {
1448 return PLDM_ERROR_INVALID_DATA;
1449 }
1450
1451 if (msg == NULL) {
1452 return PLDM_ERROR_INVALID_DATA;
1453 }
1454
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301455 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001456 header.msg_type = PLDM_REQUEST;
1457 header.instance = instance_id;
1458 header.pldm_type = PLDM_PLATFORM;
1459 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1460
1461 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1462 if (rc != PLDM_SUCCESS) {
1463 return rc;
1464 }
1465
1466 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301467 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001468 request->format_version = format_version;
1469
1470 return PLDM_SUCCESS;
1471}
1472
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301473LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301474int decode_event_message_supported_resp(const struct pldm_msg *msg,
1475 size_t payload_length,
1476 uint8_t *completion_code,
1477 uint8_t *synchrony_config,
1478 bitfield8_t *synchrony_config_support,
1479 uint8_t *number_event_class_returned,
1480 uint8_t *event_class,
1481 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001482{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301483 struct pldm_msgbuf _buf;
1484 struct pldm_msgbuf *buf = &_buf;
1485 int i;
1486 int rc;
1487
Dung Cao1bf8c872022-11-29 05:32:58 +07001488 if (msg == NULL || completion_code == NULL ||
1489 synchrony_config == NULL || synchrony_config_support == NULL ||
1490 number_event_class_returned == NULL || event_class == NULL) {
1491 return PLDM_ERROR_INVALID_DATA;
1492 }
1493
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301494 rc = pldm_msgbuf_init_errno(buf,
1495 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1496 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301497 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301498 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301499 }
1500
Andrew Jeffery66c77232024-04-24 11:42:02 +09301501 rc = pldm_msgbuf_extract_p(buf, completion_code);
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
Dung Cao1bf8c872022-11-29 05:32:58 +07001506 if (PLDM_SUCCESS != *completion_code) {
1507 return PLDM_SUCCESS;
1508 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301509
Andrew Jeffery66c77232024-04-24 11:42:02 +09301510 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301511 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301512 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001513 }
1514
Dung Cao1bf8c872022-11-29 05:32:58 +07001515 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1516 return PLDM_ERROR_INVALID_DATA;
1517 }
1518
Andrew Jeffery66c77232024-04-24 11:42:02 +09301519 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001520
Andrew Jeffery66c77232024-04-24 11:42:02 +09301521 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301522 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301523 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001524 }
1525
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301526 if (*number_event_class_returned == 0) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301527 rc = pldm_msgbuf_destroy(buf);
1528 if (rc) {
1529 return pldm_xlate_errno(rc);
1530 }
1531
1532 return PLDM_SUCCESS;
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301533 }
1534
1535 if (event_class_count < *number_event_class_returned) {
1536 return PLDM_ERROR_INVALID_LENGTH;
1537 }
1538
1539 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301540 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301541 }
1542
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301543 rc = pldm_msgbuf_destroy_consumed(buf);
1544 if (rc) {
1545 return pldm_xlate_errno(rc);
1546 }
1547
1548 return PLDM_SUCCESS;
Dung Cao1bf8c872022-11-29 05:32:58 +07001549}
1550
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301551LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301552int decode_sensor_event_data(const uint8_t *event_data,
1553 size_t event_data_length, uint16_t *sensor_id,
1554 uint8_t *sensor_event_class_type,
1555 size_t *event_class_data_offset)
1556{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301557 struct pldm_msgbuf _buf;
1558 struct pldm_msgbuf *buf = &_buf;
1559 int rc;
1560
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001561 if (event_data == NULL || sensor_id == NULL ||
1562 sensor_event_class_type == NULL ||
1563 event_class_data_offset == NULL) {
1564 return PLDM_ERROR_INVALID_DATA;
1565 }
1566
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301567 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1568 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301569 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301570 return pldm_xlate_errno(rc);
1571 }
1572
1573 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1574 return PLDM_ERROR_INVALID_LENGTH;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301575 }
1576
1577 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301578 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301579
Andrew Jeffery66c77232024-04-24 11:42:02 +09301580 pldm_msgbuf_extract_p(buf, sensor_id);
1581 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301582 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301583 return pldm_xlate_errno(rc);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301584 }
1585
1586 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301587 if (event_class_data_length !=
1588 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1589 return PLDM_ERROR_INVALID_LENGTH;
1590 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301591 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301592 if (event_class_data_length !=
1593 PLDM_SENSOR_EVENT_STATE_SENSOR_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_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301597 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301598 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301599 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301600 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301601 return PLDM_ERROR_INVALID_LENGTH;
1602 }
1603 } else {
1604 return PLDM_ERROR_INVALID_DATA;
1605 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301606
Andrew Jeffery9c766792022-08-10 23:12:49 +09301607 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301608 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301609
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301610 rc = pldm_msgbuf_destroy(buf);
1611 if (rc) {
1612 return pldm_xlate_errno(rc);
1613 }
1614
1615 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301616}
1617
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301618LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301619int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1620 uint8_t *present_op_state, uint8_t *previous_op_state)
1621{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301622 struct pldm_msgbuf _buf;
1623 struct pldm_msgbuf *buf = &_buf;
1624 int rc;
1625
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001626 if (sensor_data == NULL || present_op_state == NULL ||
1627 previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301628 return PLDM_ERROR_INVALID_DATA;
1629 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301630
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301631 rc = pldm_msgbuf_init_errno(
1632 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1633 sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301634 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301635 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301636 }
1637
Andrew Jeffery66c77232024-04-24 11:42:02 +09301638 pldm_msgbuf_extract_p(buf, present_op_state);
1639 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301640
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301641 rc = pldm_msgbuf_destroy_consumed(buf);
1642 if (rc) {
1643 return pldm_xlate_errno(rc);
1644 }
1645
1646 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301647}
1648
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301649LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301650int decode_state_sensor_data(const uint8_t *sensor_data,
1651 size_t sensor_data_length, uint8_t *sensor_offset,
1652 uint8_t *event_state,
1653 uint8_t *previous_event_state)
1654{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301655 struct pldm_msgbuf _buf;
1656 struct pldm_msgbuf *buf = &_buf;
1657 int rc;
1658
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001659 if (sensor_data == NULL || sensor_offset == NULL ||
1660 event_state == NULL || previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301661 return PLDM_ERROR_INVALID_DATA;
1662 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301663
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301664 rc = pldm_msgbuf_init_errno(
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301665 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1666 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301667 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301668 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301669 }
1670
Andrew Jeffery66c77232024-04-24 11:42:02 +09301671 pldm_msgbuf_extract_p(buf, sensor_offset);
1672 pldm_msgbuf_extract_p(buf, event_state);
1673 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301674
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301675 rc = pldm_msgbuf_destroy_consumed(buf);
1676 if (rc) {
1677 return pldm_xlate_errno(rc);
1678 }
1679
1680 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301681}
1682
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301683LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301684int decode_numeric_sensor_data(const uint8_t *sensor_data,
1685 size_t sensor_data_length, uint8_t *event_state,
1686 uint8_t *previous_event_state,
1687 uint8_t *sensor_data_size,
1688 uint32_t *present_reading)
1689{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301690 struct pldm_msgbuf _buf;
1691 struct pldm_msgbuf *buf = &_buf;
1692 int rc;
1693
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001694 if (sensor_data == NULL || sensor_data_size == NULL ||
1695 event_state == NULL || previous_event_state == NULL ||
1696 present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301697 return PLDM_ERROR_INVALID_DATA;
1698 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301699
1700 if (sensor_data_length >
1701 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301702 return PLDM_ERROR_INVALID_LENGTH;
1703 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301704
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301705 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301706 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1707 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301708 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301709 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301710 }
1711
Andrew Jeffery66c77232024-04-24 11:42:02 +09301712 pldm_msgbuf_extract_p(buf, event_state);
1713 pldm_msgbuf_extract_p(buf, previous_event_state);
1714 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301715 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301716 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301717 }
1718
1719 /*
1720 * The implementation below is bonkers, but it's because the function
1721 * prototype is bonkers. The `present_reading` argument should have been
1722 * a tagged union.
1723 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301724 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301725 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1726 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301727 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301728 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301729 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301730 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301731 }
1732 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1733 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301734 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301735 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301736 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301737 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301738 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301739 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301740 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301741 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301742 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301743 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301744 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301745 }
1746 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301747 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301748 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301749 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301750 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301751 break;
1752 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301753 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1754 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301755 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301756 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301757 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301758 break;
1759 }
1760 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1761 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301762 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301763 *present_reading = (uint32_t)val;
1764 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301765 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301766 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301767 default:
1768 return PLDM_ERROR_INVALID_DATA;
1769 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301770
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301771 rc = pldm_msgbuf_destroy_consumed(buf);
1772 if (rc) {
1773 return pldm_xlate_errno(rc);
1774 }
1775
1776 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301777}
1778
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301779LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301780int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301781 const void *pdr_data, size_t pdr_data_length,
1782 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301783{
1784 struct pldm_msgbuf _buf;
1785 struct pldm_msgbuf *buf = &_buf;
1786 int rc;
1787
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301788 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1789 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301790 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301791 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301792 }
1793
Andrew Jeffery329176a2024-09-26 22:38:24 +09301794 rc = pldm_msgbuf_extract_value_pdr_hdr(
1795 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301796 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301797 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09301798 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301799 }
1800
Andrew Jeffery66c77232024-04-24 11:42:02 +09301801 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1802 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1803 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1804 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1805 pldm_msgbuf_extract(buf, pdr_value->container_id);
1806 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1807 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1808 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1809 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1810 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1811 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1812 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1813 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1814 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1815 pldm_msgbuf_extract(buf, pdr_value->rel);
1816 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1817 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301818
Andrew Jeffery66c77232024-04-24 11:42:02 +09301819 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301820 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301821 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301822 }
1823 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1824 return PLDM_ERROR_INVALID_DATA;
1825 }
1826
Andrew Jeffery66c77232024-04-24 11:42:02 +09301827 pldm_msgbuf_extract(buf, pdr_value->resolution);
1828 pldm_msgbuf_extract(buf, pdr_value->offset);
1829 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1830 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1831 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301832 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1833 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301834 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301835 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301836 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1837 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1838 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301839 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1840 &pdr_value->max_readable);
1841 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1842 &pdr_value->min_readable);
1843
Andrew Jeffery66c77232024-04-24 11:42:02 +09301844 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301845 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301846 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301847 }
1848 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1849 return PLDM_ERROR_INVALID_DATA;
1850 }
1851
Andrew Jeffery66c77232024-04-24 11:42:02 +09301852 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301853 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301854 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301855 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301856 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301857 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301858 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301859 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301860 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301861 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301862 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301863 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301864 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301865 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301866 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301867 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301868 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301869 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301870 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301871
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301872 rc = pldm_msgbuf_destroy(buf);
1873 if (rc) {
1874 return pldm_xlate_errno(rc);
1875 }
1876
1877 return PLDM_SUCCESS;
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301878}
1879
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301880LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301881int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1882 uint16_t effecter_id,
1883 struct pldm_msg *msg)
1884{
1885 if (msg == NULL) {
1886 return PLDM_ERROR_INVALID_DATA;
1887 }
1888
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301889 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301890 header.msg_type = PLDM_REQUEST;
1891 header.instance = instance_id;
1892 header.pldm_type = PLDM_PLATFORM;
1893 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1894
1895 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1896 if (rc != PLDM_SUCCESS) {
1897 return rc;
1898 }
1899
1900 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301901 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301902 request->effecter_id = htole16(effecter_id);
1903
1904 return PLDM_SUCCESS;
1905}
1906
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301907LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301908int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301909 uint8_t instance_id, uint8_t completion_code,
1910 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1911 const uint8_t *pending_value, const uint8_t *present_value,
1912 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301913{
1914 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1915 return PLDM_ERROR_INVALID_DATA;
1916 }
1917
1918 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1919 return PLDM_ERROR_INVALID_DATA;
1920 }
1921
1922 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1923 return PLDM_ERROR_INVALID_DATA;
1924 }
1925
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301926 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301927 header.msg_type = PLDM_RESPONSE;
1928 header.instance = instance_id;
1929 header.pldm_type = PLDM_PLATFORM;
1930 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1931
1932 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1933 if (rc != PLDM_SUCCESS) {
1934 return rc;
1935 }
1936
1937 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301938 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301939
1940 response->completion_code = completion_code;
1941 response->effecter_data_size = effecter_data_size;
1942 response->effecter_oper_state = effecter_oper_state;
1943
1944 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1945 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1946 if (payload_length !=
1947 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1948 return PLDM_ERROR_INVALID_LENGTH;
1949 }
1950 response->pending_and_present_values[0] = *pending_value;
1951 response->pending_and_present_values[1] = *present_value;
1952
1953 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1954 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1955 if (payload_length !=
1956 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1957 return PLDM_ERROR_INVALID_LENGTH;
1958 }
1959 uint16_t val_pending = *(uint16_t *)pending_value;
1960 val_pending = htole16(val_pending);
1961 memcpy(response->pending_and_present_values, &val_pending,
1962 sizeof(uint16_t));
1963 uint16_t val_present = *(uint16_t *)present_value;
1964 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301965 memcpy((response->pending_and_present_values +
1966 sizeof(uint16_t)),
1967 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301968
1969 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1970 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1971 if (payload_length !=
1972 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1973 return PLDM_ERROR_INVALID_LENGTH;
1974 }
1975 uint32_t val_pending = *(uint32_t *)pending_value;
1976 val_pending = htole32(val_pending);
1977 memcpy(response->pending_and_present_values, &val_pending,
1978 sizeof(uint32_t));
1979 uint32_t val_present = *(uint32_t *)present_value;
1980 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301981 memcpy((response->pending_and_present_values +
1982 sizeof(uint32_t)),
1983 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301984 }
1985 return PLDM_SUCCESS;
1986}
1987
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301988LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301989int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1990 size_t payload_length,
1991 uint16_t *effecter_id)
1992{
Andrew Jefferydd265822023-04-13 22:42:44 +09301993 struct pldm_msgbuf _buf;
1994 struct pldm_msgbuf *buf = &_buf;
1995 int rc;
1996
Andrew Jeffery9c766792022-08-10 23:12:49 +09301997 if (msg == NULL || effecter_id == NULL) {
1998 return PLDM_ERROR_INVALID_DATA;
1999 }
2000
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302001 rc = pldm_msgbuf_init_errno(buf,
2002 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2003 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09302004 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302005 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302006 }
2007
Andrew Jeffery66c77232024-04-24 11:42:02 +09302008 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302009
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302010 rc = pldm_msgbuf_destroy_consumed(buf);
2011 if (rc) {
2012 return pldm_xlate_errno(rc);
2013 }
2014
2015 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302016}
2017
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302018LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302019int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2020 size_t payload_length,
2021 uint8_t *completion_code,
2022 uint8_t *effecter_data_size,
2023 uint8_t *effecter_oper_state,
2024 uint8_t *pending_value,
2025 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302026{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302027 struct pldm_msgbuf _buf;
2028 struct pldm_msgbuf *buf = &_buf;
2029 int rc;
2030
Andrew Jeffery9c766792022-08-10 23:12:49 +09302031 if (msg == NULL || effecter_data_size == NULL ||
2032 effecter_oper_state == NULL || pending_value == NULL ||
2033 present_value == NULL) {
2034 return PLDM_ERROR_INVALID_DATA;
2035 }
2036
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302037 rc = pldm_msgbuf_init_errno(
2038 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2039 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302040 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302041 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302042 }
2043
Andrew Jeffery66c77232024-04-24 11:42:02 +09302044 rc = pldm_msgbuf_extract_p(buf, completion_code);
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 Jeffery9c766792022-08-10 23:12:49 +09302049 if (PLDM_SUCCESS != *completion_code) {
2050 return PLDM_SUCCESS;
2051 }
2052
Andrew Jeffery66c77232024-04-24 11:42:02 +09302053 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302054 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302055 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302056 }
2057
Andrew Jeffery9c766792022-08-10 23:12:49 +09302058 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2059 return PLDM_ERROR_INVALID_DATA;
2060 }
2061
Andrew Jeffery66c77232024-04-24 11:42:02 +09302062 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302063 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302064 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302065 }
2066
Andrew Jeffery9c766792022-08-10 23:12:49 +09302067 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
2068 return PLDM_ERROR_INVALID_DATA;
2069 }
2070
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302071 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2072 pending_value);
2073 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2074 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302075
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302076 rc = pldm_msgbuf_destroy_consumed(buf);
2077 if (rc) {
2078 return pldm_xlate_errno(rc);
2079 }
2080
2081 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302082}
2083
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302084LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302085int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302086 uint8_t event_data_format, uint8_t number_of_change_records,
2087 const uint8_t *event_data_operations,
2088 const uint8_t *numbers_of_change_entries,
2089 const uint32_t *const *change_entries,
2090 struct pldm_pdr_repository_chg_event_data *event_data,
2091 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302092{
2093 if (event_data_operations == NULL ||
2094 numbers_of_change_entries == NULL || change_entries == NULL) {
2095 return PLDM_ERROR_INVALID_DATA;
2096 }
2097
2098 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302099 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302100
2101 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302102 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302103 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302104 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302105
2106 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302107 expected_size += sizeof(*change_entries[0]) *
2108 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302109 }
2110
2111 *actual_change_records_size = expected_size;
2112
2113 if (event_data == NULL) {
2114 return PLDM_SUCCESS;
2115 }
2116
2117 if (max_change_records_size < expected_size) {
2118 return PLDM_ERROR_INVALID_LENGTH;
2119 }
2120
2121 event_data->event_data_format = event_data_format;
2122 event_data->number_of_change_records = number_of_change_records;
2123
2124 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302125 (struct pldm_pdr_repository_change_record_data *)
2126 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302127
2128 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2129 record_data->event_data_operation = event_data_operations[i];
2130 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302131 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302132
2133 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2134 ++j) {
2135 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302136 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302137 }
2138
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302139 record_data =
2140 (struct pldm_pdr_repository_change_record_data
2141 *)(record_data->change_entry +
2142 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302143 }
2144
2145 return PLDM_SUCCESS;
2146}
2147
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302148LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302149int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2150 size_t event_data_size,
2151 uint8_t *event_data_format,
2152 uint8_t *number_of_change_records,
2153 size_t *change_record_data_offset)
2154{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302155 struct pldm_msgbuf _buf;
2156 struct pldm_msgbuf *buf = &_buf;
2157 int rc;
2158
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002159 if (event_data == NULL || event_data_format == NULL ||
2160 number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302161 change_record_data_offset == NULL) {
2162 return PLDM_ERROR_INVALID_DATA;
2163 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302164
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302165 rc = pldm_msgbuf_init_errno(buf,
2166 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2167 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302168 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302169 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302170 }
2171
Andrew Jeffery66c77232024-04-24 11:42:02 +09302172 pldm_msgbuf_extract_p(buf, event_data_format);
2173 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302174
Andrew Jeffery9c766792022-08-10 23:12:49 +09302175 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302176 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302177
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302178 rc = pldm_msgbuf_destroy(buf);
2179 if (rc) {
2180 return pldm_xlate_errno(rc);
2181 }
2182
2183 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302184}
2185
Thu Nguyenf874b382024-07-24 11:22:34 +00002186LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00002187int decode_pldm_message_poll_event_data(
2188 const void *event_data, size_t event_data_length,
2189 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07002190{
2191 struct pldm_msgbuf _buf;
2192 struct pldm_msgbuf *buf = &_buf;
2193 int rc;
2194
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002195 if (!event_data || !poll_event) {
Thu Nguyen7739d122024-07-26 11:36:39 +00002196 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07002197 }
2198
Thu Nguyen7739d122024-07-26 11:36:39 +00002199 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2200 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002201 if (rc) {
2202 return rc;
2203 }
2204
Thu Nguyen7739d122024-07-26 11:36:39 +00002205 pldm_msgbuf_extract(buf, poll_event->format_version);
2206 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07002207 if (rc) {
2208 return rc;
2209 }
2210
Thu Nguyen7739d122024-07-26 11:36:39 +00002211 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2212 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002213 }
2214
Thu Nguyen7739d122024-07-26 11:36:39 +00002215 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002216
2217 return pldm_msgbuf_destroy_consumed(buf);
2218}
2219
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302220LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00002221int encode_pldm_message_poll_event_data(
2222 const struct pldm_message_poll_event *poll_event, void *event_data,
2223 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07002224{
2225 struct pldm_msgbuf _buf;
2226 struct pldm_msgbuf *buf = &_buf;
2227 int rc;
2228
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002229 if (poll_event == NULL || event_data == NULL) {
2230 return -EINVAL;
2231 }
2232
Thu Nguyen7739d122024-07-26 11:36:39 +00002233 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2234 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002235 }
2236
Thu Nguyen7739d122024-07-26 11:36:39 +00002237 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2238 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002239 if (rc) {
2240 return rc;
2241 }
Thu Nguyen7739d122024-07-26 11:36:39 +00002242 pldm_msgbuf_insert(buf, poll_event->format_version);
2243 pldm_msgbuf_insert(buf, poll_event->event_id);
2244 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002245
Thu Nguyen7739d122024-07-26 11:36:39 +00002246 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002247}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302248
2249LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302250int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302251 const uint8_t *change_record_data, size_t change_record_data_size,
2252 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
2253 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302254{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302255 struct pldm_msgbuf _buf;
2256 struct pldm_msgbuf *buf = &_buf;
2257 int rc;
2258
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002259 if (change_record_data == NULL || event_data_operation == NULL ||
2260 number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302261 change_entry_data_offset == NULL) {
2262 return PLDM_ERROR_INVALID_DATA;
2263 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302264
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302265 rc = pldm_msgbuf_init_errno(
2266 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2267 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302268 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302269 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302270 }
2271
Andrew Jeffery66c77232024-04-24 11:42:02 +09302272 pldm_msgbuf_extract_p(buf, event_data_operation);
2273 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302274
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302275 *change_entry_data_offset = sizeof(*event_data_operation) +
2276 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302277
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302278 rc = pldm_msgbuf_destroy(buf);
2279 if (rc) {
2280 return pldm_xlate_errno(rc);
2281 }
2282
2283 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302284}
2285
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302286LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302287int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2288 uint8_t rearm_event_state,
2289 struct pldm_msg *msg)
2290{
2291 if (msg == NULL) {
2292 return PLDM_ERROR_INVALID_DATA;
2293 }
2294
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302295 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302296 header.msg_type = PLDM_REQUEST;
2297 header.instance = instance_id;
2298 header.pldm_type = PLDM_PLATFORM;
2299 header.command = PLDM_GET_SENSOR_READING;
2300
2301 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2302 if (rc != PLDM_SUCCESS) {
2303 return rc;
2304 }
2305
2306 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302307 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302308
2309 request->sensor_id = htole16(sensor_id);
2310 request->rearm_event_state = rearm_event_state;
2311
2312 return PLDM_SUCCESS;
2313}
2314
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302315LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302316int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302317 const struct pldm_msg *msg, size_t payload_length,
2318 uint8_t *completion_code, uint8_t *sensor_data_size,
2319 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2320 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2321 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302322{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302323 struct pldm_msgbuf _buf;
2324 struct pldm_msgbuf *buf = &_buf;
2325 int rc;
2326
Andrew Jeffery9c766792022-08-10 23:12:49 +09302327 if (msg == NULL || completion_code == NULL ||
2328 sensor_data_size == NULL || sensor_operational_state == NULL ||
2329 sensor_event_message_enable == NULL || present_state == NULL ||
2330 previous_state == NULL || event_state == NULL ||
2331 present_reading == NULL) {
2332 return PLDM_ERROR_INVALID_DATA;
2333 }
2334
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302335 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2336 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302337 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302338 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302339 }
2340
Andrew Jeffery66c77232024-04-24 11:42:02 +09302341 rc = pldm_msgbuf_extract_p(buf, completion_code);
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 Jeffery9c766792022-08-10 23:12:49 +09302346 if (PLDM_SUCCESS != *completion_code) {
2347 return PLDM_SUCCESS;
2348 }
2349
Andrew Jeffery66c77232024-04-24 11:42:02 +09302350 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302351 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302352 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302353 }
2354
Andrew Jeffery840b1402023-04-13 23:54:44 +09302355 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302356 return PLDM_ERROR_INVALID_DATA;
2357 }
2358
Andrew Jeffery66c77232024-04-24 11:42:02 +09302359 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2360 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2361 pldm_msgbuf_extract_p(buf, present_state);
2362 pldm_msgbuf_extract_p(buf, previous_state);
2363 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302364
Andrew Jeffery840b1402023-04-13 23:54:44 +09302365 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2366 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302367
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302368 rc = pldm_msgbuf_destroy_consumed(buf);
2369 if (rc) {
2370 return pldm_xlate_errno(rc);
2371 }
2372
2373 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302374}
2375
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302376LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302377int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2378 uint8_t sensor_data_size,
2379 uint8_t sensor_operational_state,
2380 uint8_t sensor_event_message_enable,
2381 uint8_t present_state,
2382 uint8_t previous_state, uint8_t event_state,
2383 const uint8_t *present_reading,
2384 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302385{
2386 if (msg == NULL || present_reading == NULL) {
2387 return PLDM_ERROR_INVALID_DATA;
2388 }
2389
2390 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2391 return PLDM_ERROR_INVALID_DATA;
2392 }
2393
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302394 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302395 header.msg_type = PLDM_RESPONSE;
2396 header.instance = instance_id;
2397 header.pldm_type = PLDM_PLATFORM;
2398 header.command = PLDM_GET_SENSOR_READING;
2399
2400 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2401 if (rc != PLDM_SUCCESS) {
2402 return rc;
2403 }
2404
2405 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302406 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302407
2408 response->completion_code = completion_code;
2409 response->sensor_data_size = sensor_data_size;
2410 response->sensor_operational_state = sensor_operational_state;
2411 response->sensor_event_message_enable = sensor_event_message_enable;
2412 response->present_state = present_state;
2413 response->previous_state = previous_state;
2414 response->event_state = event_state;
2415
2416 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2417 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2418 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2419 return PLDM_ERROR_INVALID_LENGTH;
2420 }
2421 response->present_reading[0] = *present_reading;
2422
2423 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2424 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2425 if (payload_length !=
2426 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2427 return PLDM_ERROR_INVALID_LENGTH;
2428 }
2429 uint16_t val = *(uint16_t *)present_reading;
2430 val = htole16(val);
2431 memcpy(response->present_reading, &val, 2);
2432
2433 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2434 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2435 if (payload_length !=
2436 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2437 return PLDM_ERROR_INVALID_LENGTH;
2438 }
2439 uint32_t val = *(uint32_t *)present_reading;
2440 val = htole32(val);
2441 memcpy(response->present_reading, &val, 4);
2442 }
2443
2444 return PLDM_SUCCESS;
2445}
2446
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302447LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302448int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2449 size_t payload_length, uint16_t *sensor_id,
2450 uint8_t *rearm_event_state)
2451{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302452 struct pldm_msgbuf _buf;
2453 struct pldm_msgbuf *buf = &_buf;
2454 int rc;
2455
Andrew Jeffery9c766792022-08-10 23:12:49 +09302456 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2457 return PLDM_ERROR_INVALID_DATA;
2458 }
2459
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302460 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2461 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302462 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302463 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302464 }
2465
Andrew Jeffery66c77232024-04-24 11:42:02 +09302466 pldm_msgbuf_extract_p(buf, sensor_id);
2467 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302468
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302469 rc = pldm_msgbuf_destroy(buf);
2470 if (rc) {
2471 return pldm_xlate_errno(rc);
2472 }
2473
2474 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302475}
2476
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302477LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302478int encode_set_event_receiver_req(uint8_t instance_id,
2479 uint8_t event_message_global_enable,
2480 uint8_t transport_protocol_type,
2481 uint8_t event_receiver_address_info,
2482 uint16_t heartbeat_timer,
2483 struct pldm_msg *msg)
2484{
2485 if (msg == NULL) {
2486 return PLDM_ERROR_INVALID_DATA;
2487 }
2488
2489 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2490 return PLDM_ERROR_INVALID_DATA;
2491 }
2492
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302493 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302494 header.msg_type = PLDM_REQUEST;
2495 header.instance = instance_id;
2496 header.pldm_type = PLDM_PLATFORM;
2497 header.command = PLDM_SET_EVENT_RECEIVER;
2498
2499 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2500 if (rc != PLDM_SUCCESS) {
2501 return rc;
2502 }
2503
2504 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302505 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302506 request->event_message_global_enable = event_message_global_enable;
2507
2508 request->transport_protocol_type = transport_protocol_type;
2509 request->event_receiver_address_info = event_receiver_address_info;
2510
2511 if (event_message_global_enable ==
2512 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2513 if (heartbeat_timer == 0) {
2514 return PLDM_ERROR_INVALID_DATA;
2515 }
2516 request->heartbeat_timer = htole16(heartbeat_timer);
2517 }
2518
2519 return PLDM_SUCCESS;
2520}
2521
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302522LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302523int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2524 size_t payload_length,
2525 uint8_t *completion_code)
2526{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302527 struct pldm_msgbuf _buf;
2528 struct pldm_msgbuf *buf = &_buf;
2529 int rc;
2530
Andrew Jeffery9c766792022-08-10 23:12:49 +09302531 if (msg == NULL || completion_code == NULL) {
2532 return PLDM_ERROR_INVALID_DATA;
2533 }
2534
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302535 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2536 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302537 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302538 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302539 }
2540
Andrew Jeffery66c77232024-04-24 11:42:02 +09302541 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302542
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302543 rc = pldm_msgbuf_destroy(buf);
2544 if (rc) {
2545 return pldm_xlate_errno(rc);
2546 }
2547
2548 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302549}
2550
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302551LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302552int decode_set_event_receiver_req(const struct pldm_msg *msg,
2553 size_t payload_length,
2554 uint8_t *event_message_global_enable,
2555 uint8_t *transport_protocol_type,
2556 uint8_t *event_receiver_address_info,
2557 uint16_t *heartbeat_timer)
2558
2559{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302560 struct pldm_msgbuf _buf;
2561 struct pldm_msgbuf *buf = &_buf;
2562 int rc;
2563
Andrew Jeffery9c766792022-08-10 23:12:49 +09302564 if (msg == NULL || event_message_global_enable == NULL ||
2565 transport_protocol_type == NULL ||
2566 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2567 return PLDM_ERROR_INVALID_DATA;
2568 }
2569
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302570 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2571 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302572 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302573 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302574 }
2575
Andrew Jeffery66c77232024-04-24 11:42:02 +09302576 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2577 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2578 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
Andrew Jeffery2332e052024-10-08 13:52:34 +10302579 pldm_msgbuf_extract_p(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302580
Andrew Jeffery9667f582023-04-14 00:39:21 +09302581 rc = pldm_msgbuf_destroy(buf);
2582 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302583 return pldm_xlate_errno(rc);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302584 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302585
Andrew Jeffery9c766792022-08-10 23:12:49 +09302586 if ((*event_message_global_enable ==
2587 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2588 (*heartbeat_timer == 0)) {
2589 return PLDM_ERROR_INVALID_DATA;
2590 }
2591
Andrew Jeffery9c766792022-08-10 23:12:49 +09302592 return PLDM_SUCCESS;
2593}
2594
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302595LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302596int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2597 struct pldm_msg *msg)
2598
2599{
2600 if (msg == NULL) {
2601 return PLDM_ERROR_INVALID_DATA;
2602 }
2603
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302604 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302605 header.instance = instance_id;
2606 header.msg_type = PLDM_RESPONSE;
2607 header.pldm_type = PLDM_PLATFORM;
2608 header.command = PLDM_SET_EVENT_RECEIVER;
2609
2610 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2611 if (rc != PLDM_SUCCESS) {
2612 return rc;
2613 }
2614
2615 msg->payload[0] = completion_code;
2616
2617 return PLDM_SUCCESS;
2618}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002619
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302620LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002621int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2622 uint8_t format_version,
2623 uint8_t transfer_operation_flag,
2624 uint32_t data_transfer_handle,
2625 uint16_t event_id_to_acknowledge,
2626 struct pldm_msg *msg,
2627 size_t payload_length)
2628{
2629 struct pldm_msgbuf _buf;
2630 struct pldm_msgbuf *buf = &_buf;
2631 int rc;
2632
2633 if (msg == NULL) {
2634 return PLDM_ERROR_INVALID_DATA;
2635 }
2636
Thu Nguyen387b10f2024-09-24 11:33:16 +00002637 rc = pldm_platform_poll_for_platform_event_message_validate(
2638 transfer_operation_flag, event_id_to_acknowledge);
2639 if (rc < 0) {
2640 return PLDM_ERROR_INVALID_DATA;
2641 }
2642
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302643 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002644 header.msg_type = PLDM_REQUEST;
2645 header.instance = instance_id;
2646 header.pldm_type = PLDM_PLATFORM;
2647 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2648
2649 rc = pack_pldm_header(&header, &(msg->hdr));
2650 if (rc != PLDM_SUCCESS) {
2651 return rc;
2652 }
2653
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302654 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302655 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2656 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002657 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302658 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002659 }
2660
2661 pldm_msgbuf_insert(buf, format_version);
2662 pldm_msgbuf_insert(buf, transfer_operation_flag);
2663 pldm_msgbuf_insert(buf, data_transfer_handle);
2664 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2665
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302666 rc = pldm_msgbuf_destroy(buf);
2667 if (rc) {
2668 return pldm_xlate_errno(rc);
2669 }
2670
2671 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002672}
2673
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302674LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002675int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302676 const struct pldm_msg *msg, size_t payload_length,
2677 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2678 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2679 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2680 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002681{
2682 struct pldm_msgbuf _buf;
2683 struct pldm_msgbuf *buf = &_buf;
2684 int rc;
2685
2686 if (msg == NULL || completion_code == NULL || tid == NULL ||
2687 event_id == NULL || next_data_transfer_handle == NULL ||
2688 transfer_flag == NULL || event_class == NULL ||
2689 event_data_size == NULL || event_data == NULL ||
2690 event_data_integrity_checksum == NULL) {
2691 return PLDM_ERROR_INVALID_DATA;
2692 }
2693
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302694 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302695 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2696 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002697 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302698 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002699 }
2700
Andrew Jeffery66c77232024-04-24 11:42:02 +09302701 rc = pldm_msgbuf_extract_p(buf, completion_code);
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 if (PLDM_SUCCESS != *completion_code) {
2706 return *completion_code;
2707 }
2708
Andrew Jeffery66c77232024-04-24 11:42:02 +09302709 pldm_msgbuf_extract_p(buf, tid);
2710 rc = pldm_msgbuf_extract_p(buf, event_id);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002711 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302712 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002713 }
2714 if ((*event_id == 0) || (*event_id == 0xffff)) {
2715 return PLDM_SUCCESS;
2716 }
2717
Andrew Jeffery66c77232024-04-24 11:42:02 +09302718 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2719 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002720 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302721 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002722 }
2723
Andrew Jeffery66c77232024-04-24 11:42:02 +09302724 pldm_msgbuf_extract_p(buf, event_class);
2725 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002726 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302727 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002728 }
2729 if (*event_data_size > payload_length) {
2730 return PLDM_ERROR_INVALID_DATA;
2731 }
2732
2733 if (*event_data_size > 0) {
2734 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2735 }
2736
2737 if (*transfer_flag == PLDM_END ||
2738 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302739 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002740 }
2741
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302742 rc = pldm_msgbuf_destroy_consumed(buf);
2743 if (rc) {
2744 return pldm_xlate_errno(rc);
2745 }
2746
2747 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002748}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002749
2750LIBPLDM_ABI_TESTING
2751int decode_numeric_effecter_pdr_data(
2752 const void *pdr_data, size_t pdr_data_length,
2753 struct pldm_numeric_effecter_value_pdr *pdr_value)
2754{
2755 struct pldm_msgbuf _buf;
2756 struct pldm_msgbuf *buf = &_buf;
2757 struct pldm_value_pdr_hdr hdr;
2758 int rc;
2759
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002760 if (!pdr_data || !pdr_value) {
2761 return PLDM_ERROR_INVALID_DATA;
2762 }
2763
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302764 rc = pldm_msgbuf_init_errno(buf,
2765 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2766 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002767 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302768 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002769 }
2770
Andrew Jeffery329176a2024-09-26 22:38:24 +09302771 rc = pldm_msgbuf_extract_value_pdr_hdr(
2772 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
Thu Nguyend4878cd2023-11-09 10:18:33 +07002773 pdr_data_length);
2774 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09302775 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002776 }
2777
2778 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2779
2780 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2781 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2782 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2783 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2784 pldm_msgbuf_extract(buf, pdr_value->container_id);
2785 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2786 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2787 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2788 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2789 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2790 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2791 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2792 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2793 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2794 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2795 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2796 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2797
2798 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2799 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302800 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002801 }
2802 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2803 return PLDM_ERROR_INVALID_DATA;
2804 }
2805
2806 pldm_msgbuf_extract(buf, pdr_value->resolution);
2807 pldm_msgbuf_extract(buf, pdr_value->offset);
2808 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2809 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2810 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2811 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2812 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2813 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2814 pdr_value->max_settable);
2815 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2816 pdr_value->min_settable);
2817
2818 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2819 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302820 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002821 }
2822 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2823 return PLDM_ERROR_INVALID_DATA;
2824 }
2825
2826 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2827 pldm_msgbuf_extract_range_field_format(
2828 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2829 pldm_msgbuf_extract_range_field_format(
2830 buf, pdr_value->range_field_format, pdr_value->normal_max);
2831 pldm_msgbuf_extract_range_field_format(
2832 buf, pdr_value->range_field_format, pdr_value->normal_min);
2833 pldm_msgbuf_extract_range_field_format(
2834 buf, pdr_value->range_field_format, pdr_value->rated_max);
2835 pldm_msgbuf_extract_range_field_format(
2836 buf, pdr_value->range_field_format, pdr_value->rated_min);
2837
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302838 rc = pldm_msgbuf_destroy_consumed(buf);
2839 if (rc) {
2840 return pldm_xlate_errno(rc);
2841 }
2842
2843 return PLDM_SUCCESS;
Thu Nguyend4878cd2023-11-09 10:18:33 +07002844}
Tal Yacobia6fa5552024-05-05 16:57:38 +03002845
Tal Yacobide67ab62024-05-30 22:36:50 +03002846LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002847int encode_get_state_effecter_states_req(uint8_t instance_id,
2848 uint16_t effecter_id,
2849 struct pldm_msg *msg,
2850 size_t payload_length)
2851{
2852 struct pldm_msgbuf _buf;
2853 struct pldm_msgbuf *buf = &_buf;
2854 int rc;
2855
2856 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002857 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002858 }
2859
2860 struct pldm_header_info header = { 0 };
2861 header.msg_type = PLDM_REQUEST;
2862 header.instance = instance_id;
2863 header.pldm_type = PLDM_PLATFORM;
2864 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2865
Tal Yacobif490a382024-05-31 09:57:36 +03002866 rc = pack_pldm_header_errno(&header, &msg->hdr);
2867 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002868 return rc;
2869 }
2870
Tal Yacobif490a382024-05-31 09:57:36 +03002871 rc = pldm_msgbuf_init_errno(buf,
2872 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2873 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002874 if (rc) {
2875 return rc;
2876 }
2877
2878 pldm_msgbuf_insert(buf, effecter_id);
2879
2880 return pldm_msgbuf_destroy_consumed(buf);
2881}
2882
Tal Yacobide67ab62024-05-30 22:36:50 +03002883LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002884int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
2885 size_t payload_length,
2886 uint16_t *effecter_id)
2887{
2888 struct pldm_msgbuf _buf;
2889 struct pldm_msgbuf *buf = &_buf;
2890 int rc;
2891
2892 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002893 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002894 }
2895
Tal Yacobif490a382024-05-31 09:57:36 +03002896 rc = pldm_msgbuf_init_errno(
2897 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2898 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002899 if (rc) {
2900 return rc;
2901 }
2902
2903 pldm_msgbuf_extract_p(buf, effecter_id);
2904
2905 return pldm_msgbuf_destroy_consumed(buf);
2906}
2907
Tal Yacobide67ab62024-05-30 22:36:50 +03002908LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002909int decode_get_state_effecter_states_resp(
2910 const struct pldm_msg *msg, size_t payload_length,
2911 struct pldm_get_state_effecter_states_resp *resp)
2912{
2913 struct pldm_msgbuf _buf;
2914 struct pldm_msgbuf *buf = &_buf;
2915 get_effecter_state_field *field;
2916 int rc;
2917 int i;
2918
2919 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002920 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002921 }
2922
Tal Yacobif490a382024-05-31 09:57:36 +03002923 rc = pldm_msgbuf_init_errno(
2924 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2925 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002926 if (rc) {
2927 return rc;
2928 }
2929
2930 rc = pldm_msgbuf_extract(buf, resp->completion_code);
2931 if (rc) {
2932 return rc;
2933 }
2934
2935 if (PLDM_SUCCESS != resp->completion_code) {
Tal Yacobif490a382024-05-31 09:57:36 +03002936 return 0;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002937 }
2938
2939 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
2940 if (rc) {
2941 return rc;
2942 }
2943
2944 uint8_t comp_effecter_count = resp->comp_effecter_count;
2945
2946 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2947 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002948 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002949 }
2950
2951 for (i = 0, field = resp->field; i < comp_effecter_count;
2952 i++, field++) {
2953 pldm_msgbuf_extract(buf, field->effecter_op_state);
2954 pldm_msgbuf_extract(buf, field->pending_state);
2955 pldm_msgbuf_extract(buf, field->present_state);
2956 }
2957
2958 return pldm_msgbuf_destroy_consumed(buf);
2959}
2960
Tal Yacobide67ab62024-05-30 22:36:50 +03002961LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002962int encode_get_state_effecter_states_resp(
2963 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
2964 struct pldm_msg *msg, size_t payload_length)
2965{
2966 struct pldm_msgbuf _buf;
2967 struct pldm_msgbuf *buf = &_buf;
2968 get_effecter_state_field *field;
2969 int rc;
2970 int i;
2971
2972 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002973 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002974 }
2975
2976 uint8_t comp_effecter_count = resp->comp_effecter_count;
2977
2978 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2979 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002980 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002981 }
2982
2983 struct pldm_header_info header = { 0 };
2984 header.msg_type = PLDM_RESPONSE;
2985 header.instance = instance_id;
2986 header.pldm_type = PLDM_PLATFORM;
2987 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2988
Tal Yacobif490a382024-05-31 09:57:36 +03002989 rc = pack_pldm_header_errno(&header, &msg->hdr);
2990 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002991 return rc;
2992 }
2993
Tal Yacobif490a382024-05-31 09:57:36 +03002994 rc = pldm_msgbuf_init_errno(
2995 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2996 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002997 if (rc) {
2998 return rc;
2999 }
3000
3001 pldm_msgbuf_insert(buf, resp->completion_code);
3002 pldm_msgbuf_insert(buf, comp_effecter_count);
3003
3004 for (i = 0, field = resp->field; i < comp_effecter_count;
3005 i++, field++) {
3006 pldm_msgbuf_insert(buf, field->effecter_op_state);
3007 pldm_msgbuf_insert(buf, field->pending_state);
3008 pldm_msgbuf_insert(buf, field->present_state);
3009 }
3010
3011 return pldm_msgbuf_destroy_consumed(buf);
3012}
Thu Nguyendacfa352024-06-22 09:53:15 +00003013
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003014LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003015int decode_entity_auxiliary_names_pdr(
3016 const void *data, size_t data_length,
3017 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3018{
3019 struct pldm_msgbuf _buf;
3020 struct pldm_msgbuf *buf = &_buf;
3021 struct pldm_msgbuf _src;
3022 struct pldm_msgbuf *src = &_src;
3023 struct pldm_msgbuf _dst;
3024 struct pldm_msgbuf *dst = &_dst;
3025 size_t names_len = 0;
3026 void *names = NULL;
3027 int rc;
3028 int i;
3029
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003030 if (!data || !pdr) {
3031 return -EINVAL;
3032 }
3033
Thu Nguyendacfa352024-06-22 09:53:15 +00003034 /*
3035 * Alignment of auxiliary_name_data is an invariant as we statically assert
3036 * its behaviour in the header.
3037 */
3038 assert(!((uintptr_t)pdr->auxiliary_name_data &
3039 (alignof(pldm_utf16be) - 1)));
3040
3041 /* Reject any lengths that are obviously invalid */
3042 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3043 return -EINVAL;
3044 }
3045
3046 rc = pldm_msgbuf_init_errno(
3047 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3048 data_length);
3049 if (rc) {
3050 return rc;
3051 }
3052
Andrew Jeffery329176a2024-09-26 22:38:24 +09303053 rc = pldm_msgbuf_extract_value_pdr_hdr(
3054 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
Thu Nguyendacfa352024-06-22 09:53:15 +00003055 data_length);
3056 if (rc) {
3057 return rc;
3058 }
3059
3060 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3061 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3062 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3063 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3064 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3065 if (rc < 0) {
3066 return rc;
3067 }
3068
3069 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3070 if (rc < 0) {
3071 return rc;
3072 }
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003073 assert(names);
Thu Nguyendacfa352024-06-22 09:53:15 +00003074
3075 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3076
3077 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3078 pdr->auxiliary_name_data,
3079 pdr->auxiliary_name_data_size);
3080 if (rc < 0) {
3081 return rc;
3082 }
3083
3084 /*
3085 * Below we do two passes over the same region. This is to first pack the
3086 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3087 * to maintain appropriate alignment.
3088 */
3089
3090 /* Initialise for the first pass to extract the UTF16-BE name strings */
3091 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3092 if (rc < 0) {
3093 return rc;
3094 }
3095
3096 for (i = 0; i < pdr->name_string_count; i++) {
3097 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003098 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3099 if (rc) {
3100 return rc;
3101 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003102 }
3103
3104 rc = pldm_msgbuf_destroy_consumed(src);
3105 if (rc < 0) {
3106 return rc;
3107 }
3108
3109 /* Reinitialise for the second pass to extract the ASCII tag strings */
3110 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3111 if (rc < 0) {
3112 return rc;
3113 }
3114
3115 for (i = 0; i < pdr->name_string_count; i++) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003116 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3117 if (rc) {
3118 return rc;
3119 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003120 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3121 }
3122
3123 if ((rc = pldm_msgbuf_destroy(dst)) ||
3124 (rc = pldm_msgbuf_destroy(src)) ||
3125 (rc = pldm_msgbuf_destroy(buf))) {
3126 return rc;
3127 }
3128
3129 return 0;
3130}
3131
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003132LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003133int decode_pldm_entity_auxiliary_names_pdr_index(
3134 struct pldm_entity_auxiliary_names_pdr *pdr)
3135{
3136 struct pldm_msgbuf _buf;
3137 struct pldm_msgbuf *buf = &_buf;
3138 int rc;
3139 int i;
3140
3141 if (!pdr) {
3142 return -EINVAL;
3143 }
3144
3145 if (pdr->name_string_count == 0 && pdr->names) {
3146 return -EINVAL;
3147 }
3148
3149 if (pdr->name_string_count > 0 && !pdr->names) {
3150 return -EINVAL;
3151 }
3152
3153 if (pdr->name_string_count == 0) {
3154 return 0;
3155 }
3156
3157 /*
3158 * Minimum size is one NUL for each member of each entry
3159 *
3160 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3161 * states the following:
3162 *
3163 * > A null-terminated ISO646 ASCII string ...
3164 * >
3165 * > special value: null string = 0x0000 = unspecified.
3166 *
3167 * Until proven otherwise we will assume the "0x0000" is a
3168 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3169 * represented by a single byte.
3170 */
3171 rc = pldm_msgbuf_init_errno(
3172 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3173 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3174 if (rc) {
3175 return rc;
3176 }
3177
3178 for (i = 0; i < pdr->name_string_count; i++) {
3179 void *loc = NULL;
3180 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3181 pdr->names[i].name = loc;
3182 }
3183
3184 for (i = 0; i < pdr->name_string_count; i++) {
3185 void *loc = NULL;
3186 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3187 pdr->names[i].tag = loc;
3188 }
3189
3190 return pldm_msgbuf_destroy_consumed(buf);
3191}
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003192
Thu Nguyen3559aa12024-08-29 00:13:38 +00003193LIBPLDM_ABI_STABLE
Thu Nguyen02903032024-09-03 06:39:50 +00003194int decode_pldm_platform_cper_event(const void *event_data,
3195 size_t event_data_length,
3196 struct pldm_platform_cper_event *cper_event,
3197 size_t cper_event_length)
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003198{
3199 struct pldm_msgbuf _buf;
3200 struct pldm_msgbuf *buf = &_buf;
3201 int rc;
3202
3203 if (!cper_event || !event_data) {
3204 return -EINVAL;
3205 }
3206
3207 if (cper_event_length < sizeof(*cper_event)) {
3208 return -EINVAL;
3209 }
3210
3211 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3212 event_data, event_data_length);
3213 if (rc) {
3214 return rc;
3215 }
3216
3217 pldm_msgbuf_extract(buf, cper_event->format_version);
3218 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3219 if (rc) {
3220 return rc;
3221 }
3222 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3223 cper_event->format_type !=
3224 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3225 return -EPROTO;
3226 }
3227
3228 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3229 if (rc) {
3230 return rc;
3231 }
3232
3233 if (cper_event->event_data_length >
3234 (cper_event_length - sizeof(*cper_event))) {
3235 return -EOVERFLOW;
3236 }
3237
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003238 rc = pldm_msgbuf_extract_array_uint8(
3239 buf, cper_event->event_data_length, cper_event->event_data,
3240 cper_event_length - sizeof(*cper_event));
3241 if (rc) {
3242 return rc;
3243 }
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003244
3245 return pldm_msgbuf_destroy_consumed(buf);
3246}
3247
Thu Nguyen3559aa12024-08-29 00:13:38 +00003248LIBPLDM_ABI_STABLE
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003249uint8_t *
3250pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3251{
3252 return event->event_data;
3253}