blob: 79eff6d8fa57031b7a11b4935ca6cecb2c824585 [file] [log] [blame]
Patrick Williams691668f2023-11-01 08:19:10 -05001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302#include "api.h"
3#include "compiler.h"
Tal Yacobif490a382024-05-31 09:57:36 +03004#include "dsp/base.h"
Andrew Jeffery7992eb82023-04-06 16:13:53 +09305#include "msgbuf.h"
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10306#include "msgbuf/platform.h"
7
8#include <libpldm/base.h>
9#include <libpldm/platform.h>
10#include <libpldm/pldm_types.h>
11
Andrew Jeffery9c766792022-08-10 23:12:49 +093012#include <endian.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053013#include <stdint.h>
Thu Nguyen159a98b2022-11-02 10:00:10 +070014#include <stdlib.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093015#include <string.h>
Thu Nguyendacfa352024-06-22 09:53:15 +000016#include <uchar.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093017
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093018LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093019int encode_state_effecter_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093020 struct pldm_state_effecter_pdr *const effecter,
21 const size_t allocation_size,
22 const struct state_effecter_possible_states *const possible_states,
23 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093024{
Andrew Jeffery9c766792022-08-10 23:12:49 +093025 size_t calculated_possible_states_size = 0;
26
Andrew Jefferyad33b992024-10-02 16:12:15 +093027 if (!effecter || !possible_states || !actual_size) {
28 return PLDM_ERROR;
29 }
30
31 if (SIZE_MAX - (sizeof(*effecter) - sizeof(effecter->possible_states) <
32 possible_states_size)) {
33 return PLDM_ERROR;
34 }
35
36 if (allocation_size <
37 (sizeof(*effecter) - sizeof(effecter->possible_states)) +
38 possible_states_size) {
39 return PLDM_ERROR_INVALID_LENGTH;
40 }
41
42 // Encode possible states
43
Andrew Jeffery9c766792022-08-10 23:12:49 +093044 {
45 char *states_ptr = (char *)possible_states;
46 char *const begin_states_ptr = states_ptr;
47
48 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
49 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093050 (struct state_effecter_possible_states *)
51 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093052
53 HTOLE16(states->state_set_id);
54
55 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093056 (sizeof(*states) - sizeof(states->states) +
57 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093058 }
59
60 calculated_possible_states_size = states_ptr - begin_states_ptr;
61 }
62
63 // Check lengths
64
65 if (possible_states_size != calculated_possible_states_size) {
66 *actual_size = 0;
67 return PLDM_ERROR;
68 }
69
70 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093071 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
72 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093073
Andrew Jeffery9c766792022-08-10 23:12:49 +093074 // Encode rest of PDR
75
76 effecter->hdr.version = 1;
77 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
78 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
79
80 memcpy(effecter->possible_states, possible_states,
81 possible_states_size);
82
83 // Convert effecter PDR body
84 HTOLE16(effecter->terminus_handle);
85 HTOLE16(effecter->effecter_id);
86 HTOLE16(effecter->entity_type);
87 HTOLE16(effecter->entity_instance);
88 HTOLE16(effecter->container_id);
89 HTOLE16(effecter->effecter_semantic_id);
90
91 // Convert header
92 HTOLE32(effecter->hdr.record_handle);
93 HTOLE16(effecter->hdr.record_change_num);
94 HTOLE16(effecter->hdr.length);
95
96 return PLDM_SUCCESS;
97}
98
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093099LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930100int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930101 struct pldm_state_sensor_pdr *const sensor,
102 const size_t allocation_size,
103 const struct state_sensor_possible_states *const possible_states,
104 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930105{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930106 size_t calculated_possible_states_size = 0;
107
Andrew Jefferybb50a592024-09-26 21:59:44 +0930108 if (!sensor || !possible_states || !actual_size) {
109 return PLDM_ERROR;
110 }
111
112 if (SIZE_MAX - (sizeof(*sensor) - sizeof(sensor->possible_states)) <
113 possible_states_size) {
114 return PLDM_ERROR;
115 }
116
117 if (allocation_size <
118 (sizeof(*sensor) - sizeof(sensor->possible_states) +
119 possible_states_size)) {
120 return PLDM_ERROR_INVALID_LENGTH;
121 }
122
Andrew Jeffery9c766792022-08-10 23:12:49 +0930123 {
Andrew Jefferybb50a592024-09-26 21:59:44 +0930124 // Encode possible states
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930125 char *states_ptr = (char *)possible_states;
126 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930127
128 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
129 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930130 (struct state_sensor_possible_states *)
131 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930132
133 HTOLE16(states->state_set_id);
134
135 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930136 (sizeof(*states) - sizeof(states->states) +
137 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930138 }
139
140 calculated_possible_states_size = states_ptr - begin_states_ptr;
141 }
142
143 // Check lengths
144
145 if (possible_states_size != calculated_possible_states_size) {
146 *actual_size = 0;
147 return PLDM_ERROR;
148 }
149
150 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
151 possible_states_size - sizeof(sensor->possible_states));
152
Andrew Jeffery9c766792022-08-10 23:12:49 +0930153 // Encode rest of PDR
154
155 sensor->hdr.version = 1;
156 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
157 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
158
159 memcpy(sensor->possible_states, possible_states, possible_states_size);
160
161 // Convert sensor PDR body
162 HTOLE16(sensor->terminus_handle);
163 HTOLE16(sensor->sensor_id);
164 HTOLE16(sensor->entity_type);
165 HTOLE16(sensor->entity_instance);
166 HTOLE16(sensor->container_id);
167
168 // Convert header
169 HTOLE32(sensor->hdr.record_handle);
170 HTOLE16(sensor->hdr.record_change_num);
171 HTOLE16(sensor->hdr.length);
172
173 return PLDM_SUCCESS;
174}
175
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930176LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930177int encode_set_state_effecter_states_resp(uint8_t instance_id,
178 uint8_t completion_code,
179 struct pldm_msg *msg)
180{
181 if (msg == NULL) {
182 return PLDM_ERROR_INVALID_DATA;
183 }
184
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930185 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930186 header.msg_type = PLDM_RESPONSE;
187 header.instance = instance_id;
188 header.pldm_type = PLDM_PLATFORM;
189 header.command = PLDM_SET_STATE_EFFECTER_STATES;
190
191 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
192 if (rc != PLDM_SUCCESS) {
193 return rc;
194 }
195
196 msg->payload[0] = completion_code;
197
198 return PLDM_SUCCESS;
199}
200
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930201LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930202int encode_set_state_effecter_states_req(uint8_t instance_id,
203 uint16_t effecter_id,
204 uint8_t comp_effecter_count,
205 set_effecter_state_field *field,
206 struct pldm_msg *msg)
207{
208 if (msg == NULL) {
209 return PLDM_ERROR_INVALID_DATA;
210 }
211
212 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
213 field == NULL) {
214 return PLDM_ERROR_INVALID_DATA;
215 }
216
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930217 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930218 header.msg_type = PLDM_REQUEST;
219 header.instance = instance_id;
220 header.pldm_type = PLDM_PLATFORM;
221 header.command = PLDM_SET_STATE_EFFECTER_STATES;
222
223 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
224 if (rc != PLDM_SUCCESS) {
225 return rc;
226 }
227
228 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930229 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930230 effecter_id = htole16(effecter_id);
231 request->effecter_id = effecter_id;
232 request->comp_effecter_count = comp_effecter_count;
233 memcpy(request->field, field,
234 (sizeof(set_effecter_state_field) * comp_effecter_count));
235
236 return PLDM_SUCCESS;
237}
238
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930239LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930240int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
241 size_t payload_length,
242 uint8_t *completion_code)
243{
244 if (msg == NULL || completion_code == NULL) {
245 return PLDM_ERROR_INVALID_DATA;
246 }
247
248 *completion_code = msg->payload[0];
249 if (PLDM_SUCCESS != *completion_code) {
250 return PLDM_SUCCESS;
251 }
252
253 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
254 return PLDM_ERROR_INVALID_LENGTH;
255 }
256
257 return PLDM_SUCCESS;
258}
259
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930260#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930261LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930262int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
263 size_t payload_length,
264 uint16_t *effecter_id,
265 uint8_t *comp_effecter_count,
266 set_effecter_state_field *field)
267{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930268 struct pldm_msgbuf _buf;
269 struct pldm_msgbuf *buf = &_buf;
270 int rc;
271 int i;
272
Andrew Jeffery9c766792022-08-10 23:12:49 +0930273 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
274 field == NULL) {
275 return PLDM_ERROR_INVALID_DATA;
276 }
277
278 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
279 return PLDM_ERROR_INVALID_LENGTH;
280 }
281
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930282 rc = pldm_msgbuf_init_errno(buf,
283 PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
284 msg->payload, payload_length);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930285 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930286 return pldm_xlate_errno(rc);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930287 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930288
Andrew Jeffery66c77232024-04-24 11:42:02 +0930289 pldm_msgbuf_extract_p(buf, effecter_id);
290 pldm_msgbuf_extract_p(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930291
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930292 if (*comp_effecter_count > 8) {
293 return PLDM_ERROR_INVALID_DATA;
294 }
295
296 for (i = 0; i < *comp_effecter_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930297 pldm_msgbuf_extract(buf, field[i].set_request);
298 pldm_msgbuf_extract(buf, field[i].effecter_state);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930299 }
300
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930301 rc = pldm_msgbuf_destroy(buf);
302 if (rc) {
303 return pldm_xlate_errno(rc);
304 }
305
306 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930307}
308
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930309LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930310int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
311 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
312 uint8_t *transfer_op_flag, uint16_t *request_cnt,
313 uint16_t *record_chg_num)
314{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930315 struct pldm_msgbuf _buf;
316 struct pldm_msgbuf *buf = &_buf;
317 int rc;
318
Andrew Jeffery9c766792022-08-10 23:12:49 +0930319 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
320 transfer_op_flag == NULL || request_cnt == NULL ||
321 record_chg_num == NULL) {
322 return PLDM_ERROR_INVALID_DATA;
323 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930324
Andrew Jeffery9c766792022-08-10 23:12:49 +0930325 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
326 return PLDM_ERROR_INVALID_LENGTH;
327 }
328
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930329 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
330 payload_length);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930331 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930332 return pldm_xlate_errno(rc);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930333 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930334
Andrew Jeffery66c77232024-04-24 11:42:02 +0930335 pldm_msgbuf_extract_p(buf, record_hndl);
336 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
337 pldm_msgbuf_extract_p(buf, transfer_op_flag);
338 pldm_msgbuf_extract_p(buf, request_cnt);
339 pldm_msgbuf_extract_p(buf, record_chg_num);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930340
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930341 rc = pldm_msgbuf_destroy(buf);
342 if (rc) {
343 return pldm_xlate_errno(rc);
344 }
345
346 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930347}
348
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930349LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930350int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
351 uint32_t next_record_hndl,
352 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
353 uint16_t resp_cnt, const uint8_t *record_data,
354 uint8_t transfer_crc, struct pldm_msg *msg)
355{
356 if (msg == NULL) {
357 return PLDM_ERROR_INVALID_DATA;
358 }
359
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930360 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930361 header.msg_type = PLDM_RESPONSE;
362 header.instance = instance_id;
363 header.pldm_type = PLDM_PLATFORM;
364 header.command = PLDM_GET_PDR;
365
366 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
367 if (rc != PLDM_SUCCESS) {
368 return rc;
369 }
370
371 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930372 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930373 response->completion_code = completion_code;
374
375 if (response->completion_code == PLDM_SUCCESS) {
376 response->next_record_handle = htole32(next_record_hndl);
377 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930378 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930379 response->transfer_flag = transfer_flag;
380 response->response_count = htole16(resp_cnt);
381 if (record_data != NULL && resp_cnt > 0) {
382 memcpy(response->record_data, record_data, resp_cnt);
383 }
384 if (transfer_flag == PLDM_END) {
385 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930386 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
387 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930388 *dst = transfer_crc;
389 }
390 }
391
392 return PLDM_SUCCESS;
393}
394
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930395LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930396int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930397 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
398 const uint8_t *update_time, const uint8_t *oem_update_time,
399 uint32_t record_count, uint32_t repository_size,
400 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
401 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930402{
403 if (msg == NULL) {
404 return PLDM_ERROR_INVALID_DATA;
405 }
406
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930407 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930408 header.msg_type = PLDM_RESPONSE;
409 header.instance = instance_id;
410 header.pldm_type = PLDM_PLATFORM;
411 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
412
413 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
414 if (rc != PLDM_SUCCESS) {
415 return rc;
416 }
417
418 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930419 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930420 response->completion_code = completion_code;
421
422 if (response->completion_code == PLDM_SUCCESS) {
423 response->repository_state = repository_state;
424 if (update_time != NULL) {
425 memcpy(response->update_time, update_time,
426 PLDM_TIMESTAMP104_SIZE);
427 }
428 if (oem_update_time != NULL) {
429 memcpy(response->oem_update_time, oem_update_time,
430 PLDM_TIMESTAMP104_SIZE);
431 }
432 response->record_count = htole32(record_count);
433 response->repository_size = htole32(repository_size);
434 response->largest_record_size = htole32(largest_record_size);
435 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930436 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930437 }
438
439 return PLDM_SUCCESS;
440}
441
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000442LIBPLDM_ABI_DEPRECATED
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800443int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930444 const struct pldm_msg *msg, size_t payload_length,
445 uint8_t *completion_code, uint8_t *repository_state,
446 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
447 uint32_t *repository_size, uint32_t *largest_record_size,
448 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800449{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930450 struct pldm_msgbuf _buf;
451 struct pldm_msgbuf *buf = &_buf;
452 int rc;
453
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800454 if (msg == NULL || completion_code == NULL ||
455 repository_state == NULL || update_time == NULL ||
456 oem_update_time == NULL || record_count == NULL ||
457 repository_size == NULL || largest_record_size == NULL ||
458 data_transfer_handle_timeout == NULL) {
459 return PLDM_ERROR_INVALID_DATA;
460 }
461
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930462 rc = pldm_msgbuf_init_errno(buf,
463 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
464 msg->payload, payload_length);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930465 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930466 return pldm_xlate_errno(rc);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930467 }
468
Andrew Jeffery66c77232024-04-24 11:42:02 +0930469 pldm_msgbuf_extract_p(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800470 if (PLDM_SUCCESS != *completion_code) {
471 return PLDM_SUCCESS;
472 }
473
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930474 rc = pldm_msgbuf_extract_p(buf, repository_state);
475 if (rc) {
476 return pldm_xlate_errno(rc);
477 }
478
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800479 if (*repository_state > PLDM_FAILED) {
480 return PLDM_ERROR_INVALID_DATA;
481 }
482
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000483 /* NOTE: Memory safety */
484 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
485 PLDM_TIMESTAMP104_SIZE);
486 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930487 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000488 }
489
490 /* NOTE: Memory safety */
491 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
492 oem_update_time, PLDM_TIMESTAMP104_SIZE);
493 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930494 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000495 }
496
Andrew Jeffery66c77232024-04-24 11:42:02 +0930497 pldm_msgbuf_extract_p(buf, record_count);
498 pldm_msgbuf_extract_p(buf, repository_size);
499 pldm_msgbuf_extract_p(buf, largest_record_size);
500 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800501
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930502 rc = pldm_msgbuf_destroy(buf);
503 if (rc) {
504 return pldm_xlate_errno(rc);
505 }
506
507 return PLDM_SUCCESS;
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800508}
509
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000510LIBPLDM_ABI_TESTING
511int decode_get_pdr_repository_info_resp_safe(
512 const struct pldm_msg *msg, size_t payload_length,
513 struct pldm_pdr_repository_info_resp *resp)
514{
515 struct pldm_msgbuf _buf;
516 struct pldm_msgbuf *buf = &_buf;
517 int rc;
518
519 if (msg == NULL || resp == NULL) {
520 return -EINVAL;
521 }
522
523 rc = pldm_msg_has_error(msg, payload_length);
524 if (rc) {
525 resp->completion_code = rc;
526 return 0;
527 }
528
529 rc = pldm_msgbuf_init_errno(buf,
530 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
531 msg->payload, payload_length);
532 if (rc) {
533 return rc;
534 }
535
536 rc = pldm_msgbuf_extract(buf, resp->completion_code);
537 if (rc) {
538 return rc;
539 }
540
541 pldm_msgbuf_extract(buf, resp->repository_state);
542
543 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
544 resp->update_time,
545 sizeof(resp->update_time));
546 if (rc) {
547 return rc;
548 }
549
550 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
551 resp->oem_update_time,
552 sizeof(resp->oem_update_time));
553 if (rc) {
554 return rc;
555 }
556
557 pldm_msgbuf_extract(buf, resp->record_count);
558 pldm_msgbuf_extract(buf, resp->repository_size);
559 pldm_msgbuf_extract(buf, resp->largest_record_size);
560 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
561
562 return pldm_msgbuf_destroy_consumed(buf);
563}
564
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930565LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930566int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
567 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
568 uint16_t request_cnt, uint16_t record_chg_num,
569 struct pldm_msg *msg, size_t payload_length)
570{
571 if (msg == NULL) {
572 return PLDM_ERROR_INVALID_DATA;
573 }
574
575 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
576 return PLDM_ERROR_INVALID_LENGTH;
577 }
578
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930579 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930580 header.msg_type = PLDM_REQUEST;
581 header.instance = instance_id;
582 header.pldm_type = PLDM_PLATFORM;
583 header.command = PLDM_GET_PDR;
584
585 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
586 if (rc != PLDM_SUCCESS) {
587 return rc;
588 }
589
590 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930591 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930592 request->record_handle = htole32(record_hndl);
593 request->data_transfer_handle = htole32(data_transfer_hndl);
594 request->transfer_op_flag = transfer_op_flag;
595 request->request_count = htole16(request_cnt);
596 request->record_change_number = htole16(record_chg_num);
597
598 return PLDM_SUCCESS;
599}
600
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000601LIBPLDM_ABI_DEPRECATED
Andrew Jeffery9c766792022-08-10 23:12:49 +0930602int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
603 uint8_t *completion_code, uint32_t *next_record_hndl,
604 uint32_t *next_data_transfer_hndl,
605 uint8_t *transfer_flag, uint16_t *resp_cnt,
606 uint8_t *record_data, size_t record_data_length,
607 uint8_t *transfer_crc)
608{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930609 struct pldm_msgbuf _buf;
610 struct pldm_msgbuf *buf = &_buf;
611 int rc;
612
Andrew Jeffery9c766792022-08-10 23:12:49 +0930613 if (msg == NULL || completion_code == NULL ||
614 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
615 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
616 return PLDM_ERROR_INVALID_DATA;
617 }
618
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930619 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
620 msg->payload, payload_length);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930621 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930622 return pldm_xlate_errno(rc);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930623 }
624
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930625 rc = pldm_msgbuf_extract_p(buf, completion_code);
626 if (rc) {
627 return pldm_xlate_errno(rc);
628 }
629
Andrew Jeffery9c766792022-08-10 23:12:49 +0930630 if (PLDM_SUCCESS != *completion_code) {
631 return PLDM_SUCCESS;
632 }
633
Andrew Jeffery66c77232024-04-24 11:42:02 +0930634 pldm_msgbuf_extract_p(buf, next_record_hndl);
635 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
636 pldm_msgbuf_extract_p(buf, transfer_flag);
637 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930638 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930639 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930640 }
641
642 if (*resp_cnt > 0 && record_data != NULL) {
643 if (record_data_length < *resp_cnt) {
644 return PLDM_ERROR_INVALID_LENGTH;
645 }
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000646 /* NOTE: Memory safety */
647 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
648 *resp_cnt);
649 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930650 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000651 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930652 }
653
654 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930655 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930656 }
657
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930658 rc = pldm_msgbuf_destroy(buf);
659 if (rc) {
660 return pldm_xlate_errno(rc);
661 }
662
663 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930664}
665
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +0000666LIBPLDM_ABI_TESTING
667int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
668 struct pldm_get_pdr_resp *resp, size_t resp_len,
669 uint8_t *transfer_crc)
670{
671 struct pldm_msgbuf _buf;
672 struct pldm_msgbuf *buf = &_buf;
673 int rc;
674
675 if (msg == NULL || resp == NULL || transfer_crc == NULL) {
676 return -EINVAL;
677 }
678
679 rc = pldm_msg_has_error(msg, payload_length);
680 if (rc) {
681 resp->completion_code = rc;
682 return 0;
683 }
684
685 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
686 msg->payload, payload_length);
687 if (rc) {
688 return rc;
689 }
690
691 pldm_msgbuf_extract(buf, resp->completion_code);
692 pldm_msgbuf_extract(buf, resp->next_record_handle);
693 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
694
695 rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
696 if (rc) {
697 return rc;
698 }
699
700 rc = pldm_msgbuf_extract(buf, resp->response_count);
701 if (rc) {
702 return rc;
703 }
704
705 rc = pldm_msgbuf_extract_array(
706 buf, resp->response_count, resp->record_data,
707 resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
708 if (rc) {
709 return rc;
710 }
711
712 if (resp->transfer_flag == PLDM_END) {
713 pldm_msgbuf_extract_p(buf, transfer_crc);
714 }
715
716 return pldm_msgbuf_destroy_consumed(buf);
717}
718
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930719LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930720int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
721 size_t payload_length,
722 uint16_t *effecter_id,
723 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930724 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930725{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930726 struct pldm_msgbuf _buf;
727 struct pldm_msgbuf *buf = &_buf;
728 int rc;
729
Andrew Jeffery9c766792022-08-10 23:12:49 +0930730 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
731 effecter_value == NULL) {
732 return PLDM_ERROR_INVALID_DATA;
733 }
734
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930735 rc = pldm_msgbuf_init_errno(
736 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
737 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930738 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930739 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930740 }
741
Andrew Jeffery66c77232024-04-24 11:42:02 +0930742 pldm_msgbuf_extract_p(buf, effecter_id);
743 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930744 if (rc) {
745 return PLDM_ERROR_INVALID_DATA;
746 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930747
748 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
749 return PLDM_ERROR_INVALID_DATA;
750 }
751
Andrew Jeffery3884c442023-04-12 11:13:24 +0930752 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
753 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930754
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930755 rc = pldm_msgbuf_destroy(buf);
756 if (rc) {
757 return pldm_xlate_errno(rc);
758 }
759
760 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930761}
762
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930763LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930764int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
765 uint8_t completion_code,
766 struct pldm_msg *msg,
767 size_t payload_length)
768{
769 if (msg == NULL) {
770 return PLDM_ERROR_INVALID_DATA;
771 }
772
773 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
774 return PLDM_ERROR_INVALID_LENGTH;
775 }
776
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930777 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930778 header.msg_type = PLDM_RESPONSE;
779 header.instance = instance_id;
780 header.pldm_type = PLDM_PLATFORM;
781 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
782
783 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
784 if (rc != PLDM_SUCCESS) {
785 return rc;
786 }
787
788 msg->payload[0] = completion_code;
789
790 return rc;
791}
792
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930793LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930794int encode_set_numeric_effecter_value_req(uint8_t instance_id,
795 uint16_t effecter_id,
796 uint8_t effecter_data_size,
797 const uint8_t *effecter_value,
798 struct pldm_msg *msg,
799 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930800{
801 if (msg == NULL || effecter_value == NULL) {
802 return PLDM_ERROR_INVALID_DATA;
803 }
804
805 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
806 return PLDM_ERROR_INVALID_DATA;
807 }
808
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930809 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930810 header.msg_type = PLDM_REQUEST;
811 header.instance = instance_id;
812 header.pldm_type = PLDM_PLATFORM;
813 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
814
815 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
816 if (rc != PLDM_SUCCESS) {
817 return rc;
818 }
819
820 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930821 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930822 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
823 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
824 if (payload_length !=
825 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
826 return PLDM_ERROR_INVALID_LENGTH;
827 }
828 request->effecter_value[0] = *effecter_value;
829 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
830 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
831 if (payload_length !=
832 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
833 return PLDM_ERROR_INVALID_LENGTH;
834 }
835
836 uint16_t val = *(uint16_t *)(effecter_value);
837 val = htole16(val);
838 memcpy(request->effecter_value, &val, sizeof(uint16_t));
839
840 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
841 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
842 if (payload_length !=
843 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
844 return PLDM_ERROR_INVALID_LENGTH;
845 }
846
847 uint32_t val = *(uint32_t *)(effecter_value);
848 val = htole32(val);
849 memcpy(request->effecter_value, &val, sizeof(uint32_t));
850 }
851
852 request->effecter_id = htole16(effecter_id);
853 request->effecter_data_size = effecter_data_size;
854
855 return PLDM_SUCCESS;
856}
857
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930858LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930859int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
860 size_t payload_length,
861 uint8_t *completion_code)
862{
863 if (msg == NULL || completion_code == NULL) {
864 return PLDM_ERROR_INVALID_DATA;
865 }
866
867 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
868 return PLDM_ERROR_INVALID_LENGTH;
869 }
870
871 *completion_code = msg->payload[0];
872
873 return PLDM_SUCCESS;
874}
875
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930876LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930877int encode_get_state_sensor_readings_resp(uint8_t instance_id,
878 uint8_t completion_code,
879 uint8_t comp_sensor_count,
880 get_sensor_state_field *field,
881 struct pldm_msg *msg)
882{
883 if (msg == NULL) {
884 return PLDM_ERROR_INVALID_DATA;
885 }
886
887 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
888 return PLDM_ERROR_INVALID_DATA;
889 }
890
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930891 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930892 header.msg_type = PLDM_RESPONSE;
893 header.instance = instance_id;
894 header.pldm_type = PLDM_PLATFORM;
895 header.command = PLDM_GET_STATE_SENSOR_READINGS;
896
897 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
898 if (rc != PLDM_SUCCESS) {
899 return rc;
900 }
901
902 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930903 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930904
905 response->completion_code = completion_code;
906 response->comp_sensor_count = comp_sensor_count;
907 memcpy(response->field, field,
908 (sizeof(get_sensor_state_field) * comp_sensor_count));
909
910 return PLDM_SUCCESS;
911}
912
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930913LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930914int encode_get_state_sensor_readings_req(uint8_t instance_id,
915 uint16_t sensor_id,
916 bitfield8_t sensor_rearm,
917 uint8_t reserved, struct pldm_msg *msg)
918{
919 if (msg == NULL) {
920 return PLDM_ERROR_INVALID_DATA;
921 }
922
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930923 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930924 header.msg_type = PLDM_REQUEST;
925 header.instance = instance_id;
926 header.pldm_type = PLDM_PLATFORM;
927 header.command = PLDM_GET_STATE_SENSOR_READINGS;
928
929 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
930 if (rc != PLDM_SUCCESS) {
931 return rc;
932 }
933
934 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930935 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930936
937 request->sensor_id = htole16(sensor_id);
938 request->reserved = reserved;
939 request->sensor_rearm = sensor_rearm;
940
941 return PLDM_SUCCESS;
942}
943
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930944LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930945int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
946 size_t payload_length,
947 uint8_t *completion_code,
948 uint8_t *comp_sensor_count,
949 get_sensor_state_field *field)
950{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930951 struct pldm_msgbuf _buf;
952 struct pldm_msgbuf *buf = &_buf;
953 uint8_t i;
954 int rc;
955
Andrew Jeffery9c766792022-08-10 23:12:49 +0930956 if (msg == NULL || completion_code == NULL ||
957 comp_sensor_count == NULL || field == NULL) {
958 return PLDM_ERROR_INVALID_DATA;
959 }
960
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930961 rc = pldm_msgbuf_init_errno(
962 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
963 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930964 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930965 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930966 }
967
Andrew Jeffery66c77232024-04-24 11:42:02 +0930968 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930969 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930970 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930971 }
972
Andrew Jeffery9c766792022-08-10 23:12:49 +0930973 if (PLDM_SUCCESS != *completion_code) {
974 return PLDM_SUCCESS;
975 }
976
Andrew Jeffery66c77232024-04-24 11:42:02 +0930977 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930978 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930979 return pldm_xlate_errno(rc);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930980 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930981
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930982 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930983 return PLDM_ERROR_INVALID_DATA;
984 }
985
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930986 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930987 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
988 pldm_msgbuf_extract(buf, field[i].present_state);
989 pldm_msgbuf_extract(buf, field[i].previous_state);
990 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930991 }
992
Andrew Jeffery830c1eb2024-10-04 10:48:10 +0930993 rc = pldm_msgbuf_destroy_consumed(buf);
994 if (rc) {
995 return pldm_xlate_errno(rc);
996 }
997
998 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930999}
1000
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301001LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301002int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
1003 size_t payload_length,
1004 uint16_t *sensor_id,
1005 bitfield8_t *sensor_rearm,
1006 uint8_t *reserved)
1007{
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301008 struct pldm_msgbuf _buf;
1009 struct pldm_msgbuf *buf = &_buf;
1010 int rc;
1011
Andrew Jeffery9c766792022-08-10 23:12:49 +09301012 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
1013 return PLDM_ERROR_INVALID_DATA;
1014 }
1015
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301016 rc = pldm_msgbuf_init_errno(buf,
1017 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
1018 msg->payload, payload_length);
Andrew Jefferyf75aca62023-04-13 11:27:07 +09301019 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301020 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301021 }
1022
Andrew Jeffery66c77232024-04-24 11:42:02 +09301023 pldm_msgbuf_extract_p(buf, sensor_id);
1024 pldm_msgbuf_extract(buf, sensor_rearm->byte);
1025 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301026
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301027 rc = pldm_msgbuf_destroy(buf);
1028 if (rc) {
1029 return pldm_xlate_errno(rc);
1030 }
1031
1032 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301033}
1034
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301035LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301036int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301037 struct pldm_sensor_event_data *const event_data,
1038 const size_t event_data_size, const uint16_t sensor_id,
1039 const enum sensor_event_class_states sensor_event_class,
1040 const uint8_t sensor_offset, const uint8_t event_state,
1041 const uint8_t previous_event_state,
1042 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301043{
1044 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301045 (sizeof(*event_data) - sizeof(event_data->event_class) +
1046 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301047
1048 if (!event_data) {
1049 return PLDM_SUCCESS;
1050 }
1051
1052 if (event_data_size < *actual_event_data_size) {
1053 *actual_event_data_size = 0;
1054 return PLDM_ERROR_INVALID_LENGTH;
1055 }
1056
1057 event_data->sensor_id = htole16(sensor_id);
1058 event_data->sensor_event_class_type = sensor_event_class;
1059
1060 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301061 (struct pldm_sensor_event_state_sensor_state *)
1062 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301063
1064 state_data->sensor_offset = sensor_offset;
1065 state_data->event_state = event_state;
1066 state_data->previous_event_state = previous_event_state;
1067
1068 return PLDM_SUCCESS;
1069}
1070
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301071LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301072int decode_platform_event_message_req(const struct pldm_msg *msg,
1073 size_t payload_length,
1074 uint8_t *format_version, uint8_t *tid,
1075 uint8_t *event_class,
1076 size_t *event_data_offset)
1077{
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301078 struct pldm_msgbuf _buf;
1079 struct pldm_msgbuf *buf = &_buf;
1080 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301081
1082 if (msg == NULL || format_version == NULL || tid == NULL ||
1083 event_class == NULL || event_data_offset == NULL) {
1084 return PLDM_ERROR_INVALID_DATA;
1085 }
1086
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301087 rc = pldm_msgbuf_init_errno(buf,
1088 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
1089 msg->payload, payload_length);
Andrew Jefferydc48ce32023-04-13 12:01:42 +09301090 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301091 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301092 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301093
Andrew Jeffery66c77232024-04-24 11:42:02 +09301094 pldm_msgbuf_extract_p(buf, format_version);
1095 pldm_msgbuf_extract_p(buf, tid);
1096 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301097
1098 rc = pldm_msgbuf_destroy(buf);
1099 if (rc) {
1100 return pldm_xlate_errno(rc);
1101 }
1102
Andrew Jeffery9c766792022-08-10 23:12:49 +09301103 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301104 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301105
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301106 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301107}
1108
Thu Nguyen387b10f2024-09-24 11:33:16 +00001109static int pldm_platform_poll_for_platform_event_message_validate(
1110 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1111{
1112 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1113 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1114 ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1115 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1116 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
Thu Nguyen9e16b182024-10-01 03:12:16 +00001117 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1118 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1119 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
Thu Nguyen387b10f2024-09-24 11:33:16 +00001120 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1121 return -EPROTO;
1122 }
1123
1124 return 0;
1125}
1126
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301127LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001128int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301129 const struct pldm_msg *msg, size_t payload_length,
1130 uint8_t *format_version, uint8_t *transfer_operation_flag,
1131 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001132{
1133 struct pldm_msgbuf _buf;
1134 struct pldm_msgbuf *buf = &_buf;
1135 int rc;
1136
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001137 if (msg == NULL || format_version == NULL ||
1138 transfer_operation_flag == NULL || data_transfer_handle == NULL ||
1139 event_id_to_acknowledge == NULL) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001140 return PLDM_ERROR_INVALID_DATA;
1141 }
1142
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301143 rc = pldm_msgbuf_init_errno(
1144 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
1145 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001146 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301147 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001148 }
1149
Andrew Jeffery66c77232024-04-24 11:42:02 +09301150 pldm_msgbuf_extract_p(buf, format_version);
1151 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001152 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301153 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001154 }
1155 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
1156 return PLDM_ERROR_INVALID_DATA;
1157 }
1158
Andrew Jeffery66c77232024-04-24 11:42:02 +09301159 pldm_msgbuf_extract_p(buf, data_transfer_handle);
1160 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001161 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301162 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001163 }
1164
Thu Nguyen387b10f2024-09-24 11:33:16 +00001165 rc = pldm_platform_poll_for_platform_event_message_validate(
1166 *transfer_operation_flag, *event_id_to_acknowledge);
1167 if (rc < 0) {
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001168 return PLDM_ERROR_INVALID_DATA;
1169 }
1170
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301171 rc = pldm_msgbuf_destroy(buf);
1172 if (rc) {
1173 return pldm_xlate_errno(rc);
1174 }
1175
1176 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001177}
1178
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301179LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301180int encode_platform_event_message_resp(uint8_t instance_id,
1181 uint8_t completion_code,
1182 uint8_t platform_event_status,
1183 struct pldm_msg *msg)
1184{
1185 if (msg == NULL) {
1186 return PLDM_ERROR_INVALID_DATA;
1187 }
1188
1189 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1190 return PLDM_ERROR_INVALID_DATA;
1191 }
1192
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301193 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301194 header.msg_type = PLDM_RESPONSE;
1195 header.instance = instance_id;
1196 header.pldm_type = PLDM_PLATFORM;
1197 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1198
1199 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1200 if (rc != PLDM_SUCCESS) {
1201 return rc;
1202 }
1203
1204 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301205 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301206 response->completion_code = completion_code;
1207 response->platform_event_status = platform_event_status;
1208
1209 return PLDM_SUCCESS;
1210}
1211
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301212LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001213int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301214 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1215 uint16_t event_id, uint32_t next_data_transfer_handle,
1216 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1217 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1218 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001219{
1220 struct pldm_msgbuf _buf;
1221 struct pldm_msgbuf *buf = &_buf;
1222 int rc;
1223
1224 if (!msg) {
1225 return PLDM_ERROR_INVALID_DATA;
1226 }
1227
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301228 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001229 header.msg_type = PLDM_RESPONSE;
1230 header.instance = instance_id;
1231 header.pldm_type = PLDM_PLATFORM;
1232 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1233
1234 rc = pack_pldm_header(&header, &(msg->hdr));
1235 if (rc != PLDM_SUCCESS) {
1236 return rc;
1237 }
1238
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301239 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301240 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1241 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001242 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301243 return pldm_xlate_errno(rc);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001244 }
1245
1246 pldm_msgbuf_insert(buf, completion_code);
1247 pldm_msgbuf_insert(buf, tid);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301248 rc = pldm_msgbuf_insert(buf, event_id);
1249 if (rc) {
1250 return pldm_xlate_errno(rc);
1251 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001252
1253 if (event_id == 0xffff || event_id == 0x0000) {
1254 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1255 payload_length) {
1256 return PLDM_ERROR_INVALID_LENGTH;
1257 }
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301258
1259 rc = pldm_msgbuf_destroy(buf);
1260 if (rc) {
1261 return pldm_xlate_errno(rc);
1262 }
1263
1264 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001265 }
1266
1267 if ((event_data == NULL) && (event_data_size > 0)) {
1268 return PLDM_ERROR_INVALID_DATA;
1269 }
1270
1271 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1272 pldm_msgbuf_insert(buf, transfer_flag);
1273 pldm_msgbuf_insert(buf, event_class);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301274 rc = pldm_msgbuf_insert(buf, event_data_size);
1275 if (rc) {
1276 return pldm_xlate_errno(rc);
1277 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001278
1279 if ((event_data_size > 0) && event_data) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001280 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
1281 event_data_size);
1282 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301283 return pldm_xlate_errno(rc);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00001284 }
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001285 }
1286
1287 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1288 pldm_msgbuf_insert(buf, checksum);
1289 }
1290
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301291 rc = pldm_msgbuf_destroy(buf);
1292 if (rc) {
1293 return pldm_xlate_errno(rc);
1294 }
1295
1296 return PLDM_SUCCESS;
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001297}
1298
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301299LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301300int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301301 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1302 uint8_t event_class, const uint8_t *event_data,
1303 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301304
1305{
1306 if (format_version != 1) {
1307 return PLDM_ERROR_INVALID_DATA;
1308 }
1309
1310 if (msg == NULL || event_data == NULL) {
1311 return PLDM_ERROR_INVALID_DATA;
1312 }
1313
1314 if (event_data_length == 0) {
1315 return PLDM_ERROR_INVALID_DATA;
1316 }
1317
Andrew Jeffery225530a2024-09-25 13:11:43 +09301318 if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1319 event_data_length) {
1320 return PLDM_ERROR_INVALID_LENGTH;
1321 }
1322
Andrew Jeffery9c766792022-08-10 23:12:49 +09301323 if (payload_length !=
1324 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1325 return PLDM_ERROR_INVALID_LENGTH;
1326 }
1327
John Chungb43a7782024-09-26 22:04:27 +08001328 if (event_class > PLDM_CPER_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001329 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301330 return PLDM_ERROR_INVALID_DATA;
1331 }
1332
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301333 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301334 header.msg_type = PLDM_REQUEST;
1335 header.instance = instance_id;
1336 header.pldm_type = PLDM_PLATFORM;
1337 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1338
1339 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1340 if (rc != PLDM_SUCCESS) {
1341 return rc;
1342 }
1343
1344 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301345 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301346 request->format_version = format_version;
1347 request->tid = tid;
1348 request->event_class = event_class;
1349 memcpy(request->event_data, event_data, event_data_length);
1350
1351 return PLDM_SUCCESS;
1352}
1353
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301354LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301355int decode_platform_event_message_resp(const struct pldm_msg *msg,
1356 size_t payload_length,
1357 uint8_t *completion_code,
1358 uint8_t *platform_event_status)
1359{
Andrew Jefferye5011772023-04-13 12:06:22 +09301360 struct pldm_msgbuf _buf;
1361 struct pldm_msgbuf *buf = &_buf;
1362 int rc;
1363
Andrew Jeffery9c766792022-08-10 23:12:49 +09301364 if (msg == NULL || completion_code == NULL ||
1365 platform_event_status == NULL) {
1366 return PLDM_ERROR_INVALID_DATA;
1367 }
1368
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301369 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1370 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301371 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301372 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301373 }
1374
Andrew Jeffery66c77232024-04-24 11:42:02 +09301375 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301376 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301377 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301378 }
1379
Andrew Jeffery9c766792022-08-10 23:12:49 +09301380 if (PLDM_SUCCESS != *completion_code) {
1381 return PLDM_SUCCESS;
1382 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301383
Andrew Jeffery66c77232024-04-24 11:42:02 +09301384 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301385 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301386 return pldm_xlate_errno(rc);
Andrew Jefferye5011772023-04-13 12:06:22 +09301387 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301388
1389 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1390 return PLDM_ERROR_INVALID_DATA;
1391 }
1392
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301393 rc = pldm_msgbuf_destroy(buf);
1394 if (rc) {
1395 return pldm_xlate_errno(rc);
1396 }
1397
1398 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301399}
1400
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301401LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301402int encode_event_message_buffer_size_req(uint8_t instance_id,
1403 uint16_t event_receiver_max_buffer_size,
1404 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001405{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301406 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001407 header.msg_type = PLDM_REQUEST;
1408 header.instance = instance_id;
1409 header.pldm_type = PLDM_PLATFORM;
1410 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1411
1412 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1413 if (rc != PLDM_SUCCESS) {
1414 return rc;
1415 }
1416
1417 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301418 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001419 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301420 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001421
1422 return PLDM_SUCCESS;
1423}
1424
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301425LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001426int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1427 size_t payload_length,
1428 uint8_t *completion_code,
1429 uint16_t *terminus_max_buffer_size)
1430{
Andrew Jeffery11126902023-04-13 12:12:10 +09301431 struct pldm_msgbuf _buf;
1432 struct pldm_msgbuf *buf = &_buf;
1433 int rc;
1434
Dung Caod6ae8982022-11-02 10:00:10 +07001435 if (msg == NULL || completion_code == NULL ||
1436 terminus_max_buffer_size == NULL) {
1437 return PLDM_ERROR_INVALID_DATA;
1438 }
1439
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301440 rc = pldm_msgbuf_init_errno(buf,
1441 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1442 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301443 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301444 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301445 }
1446
Andrew Jeffery66c77232024-04-24 11:42:02 +09301447 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301448 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301449 return pldm_xlate_errno(rc);
Andrew Jeffery11126902023-04-13 12:12:10 +09301450 }
1451
Dung Caod6ae8982022-11-02 10:00:10 +07001452 if (PLDM_SUCCESS != *completion_code) {
1453 return PLDM_SUCCESS;
1454 }
Dung Caod6ae8982022-11-02 10:00:10 +07001455
Andrew Jeffery66c77232024-04-24 11:42:02 +09301456 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001457
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301458 rc = pldm_msgbuf_destroy_consumed(buf);
1459 if (rc) {
1460 return pldm_xlate_errno(rc);
1461 }
1462
1463 return PLDM_SUCCESS;
Dung Caod6ae8982022-11-02 10:00:10 +07001464}
1465
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301466LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001467int encode_event_message_supported_req(uint8_t instance_id,
1468 uint8_t format_version,
1469 struct pldm_msg *msg)
1470{
1471 if (format_version != 1) {
1472 return PLDM_ERROR_INVALID_DATA;
1473 }
1474
1475 if (msg == NULL) {
1476 return PLDM_ERROR_INVALID_DATA;
1477 }
1478
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301479 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001480 header.msg_type = PLDM_REQUEST;
1481 header.instance = instance_id;
1482 header.pldm_type = PLDM_PLATFORM;
1483 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1484
1485 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1486 if (rc != PLDM_SUCCESS) {
1487 return rc;
1488 }
1489
1490 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301491 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001492 request->format_version = format_version;
1493
1494 return PLDM_SUCCESS;
1495}
1496
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301497LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301498int decode_event_message_supported_resp(const struct pldm_msg *msg,
1499 size_t payload_length,
1500 uint8_t *completion_code,
1501 uint8_t *synchrony_config,
1502 bitfield8_t *synchrony_config_support,
1503 uint8_t *number_event_class_returned,
1504 uint8_t *event_class,
1505 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001506{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301507 struct pldm_msgbuf _buf;
1508 struct pldm_msgbuf *buf = &_buf;
1509 int i;
1510 int rc;
1511
Dung Cao1bf8c872022-11-29 05:32:58 +07001512 if (msg == NULL || completion_code == NULL ||
1513 synchrony_config == NULL || synchrony_config_support == NULL ||
1514 number_event_class_returned == NULL || event_class == NULL) {
1515 return PLDM_ERROR_INVALID_DATA;
1516 }
1517
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301518 rc = pldm_msgbuf_init_errno(buf,
1519 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1520 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301521 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301522 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301523 }
1524
Andrew Jeffery66c77232024-04-24 11:42:02 +09301525 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301526 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301527 return pldm_xlate_errno(rc);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301528 }
1529
Dung Cao1bf8c872022-11-29 05:32:58 +07001530 if (PLDM_SUCCESS != *completion_code) {
1531 return PLDM_SUCCESS;
1532 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301533
Andrew Jeffery66c77232024-04-24 11:42:02 +09301534 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301535 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301536 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001537 }
1538
Dung Cao1bf8c872022-11-29 05:32:58 +07001539 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1540 return PLDM_ERROR_INVALID_DATA;
1541 }
1542
Andrew Jeffery66c77232024-04-24 11:42:02 +09301543 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001544
Andrew Jeffery66c77232024-04-24 11:42:02 +09301545 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301546 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301547 return pldm_xlate_errno(rc);
Dung Cao1bf8c872022-11-29 05:32:58 +07001548 }
1549
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301550 if (*number_event_class_returned == 0) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301551 rc = pldm_msgbuf_destroy(buf);
1552 if (rc) {
1553 return pldm_xlate_errno(rc);
1554 }
1555
1556 return PLDM_SUCCESS;
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301557 }
1558
1559 if (event_class_count < *number_event_class_returned) {
1560 return PLDM_ERROR_INVALID_LENGTH;
1561 }
1562
1563 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301564 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301565 }
1566
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301567 rc = pldm_msgbuf_destroy_consumed(buf);
1568 if (rc) {
1569 return pldm_xlate_errno(rc);
1570 }
1571
1572 return PLDM_SUCCESS;
Dung Cao1bf8c872022-11-29 05:32:58 +07001573}
1574
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301575LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301576int decode_sensor_event_data(const uint8_t *event_data,
1577 size_t event_data_length, uint16_t *sensor_id,
1578 uint8_t *sensor_event_class_type,
1579 size_t *event_class_data_offset)
1580{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301581 struct pldm_msgbuf _buf;
1582 struct pldm_msgbuf *buf = &_buf;
1583 int rc;
1584
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001585 if (event_data == NULL || sensor_id == NULL ||
1586 sensor_event_class_type == NULL ||
1587 event_class_data_offset == NULL) {
1588 return PLDM_ERROR_INVALID_DATA;
1589 }
1590
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301591 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1592 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301593 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301594 return pldm_xlate_errno(rc);
1595 }
1596
1597 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1598 return PLDM_ERROR_INVALID_LENGTH;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301599 }
1600
1601 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301602 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301603
Andrew Jeffery66c77232024-04-24 11:42:02 +09301604 pldm_msgbuf_extract_p(buf, sensor_id);
1605 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301606 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301607 return pldm_xlate_errno(rc);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301608 }
1609
1610 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301611 if (event_class_data_length !=
1612 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1613 return PLDM_ERROR_INVALID_LENGTH;
1614 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301615 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301616 if (event_class_data_length !=
1617 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1618 return PLDM_ERROR_INVALID_LENGTH;
1619 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301620 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301621 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301622 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301623 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301624 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301625 return PLDM_ERROR_INVALID_LENGTH;
1626 }
1627 } else {
1628 return PLDM_ERROR_INVALID_DATA;
1629 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301630
Andrew Jeffery9c766792022-08-10 23:12:49 +09301631 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301632 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301633
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301634 rc = pldm_msgbuf_destroy(buf);
1635 if (rc) {
1636 return pldm_xlate_errno(rc);
1637 }
1638
1639 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301640}
1641
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301642LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301643int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1644 uint8_t *present_op_state, uint8_t *previous_op_state)
1645{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301646 struct pldm_msgbuf _buf;
1647 struct pldm_msgbuf *buf = &_buf;
1648 int rc;
1649
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001650 if (sensor_data == NULL || present_op_state == NULL ||
1651 previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301652 return PLDM_ERROR_INVALID_DATA;
1653 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301654
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301655 rc = pldm_msgbuf_init_errno(
1656 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1657 sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301658 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301659 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301660 }
1661
Andrew Jeffery66c77232024-04-24 11:42:02 +09301662 pldm_msgbuf_extract_p(buf, present_op_state);
1663 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301664
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301665 rc = pldm_msgbuf_destroy_consumed(buf);
1666 if (rc) {
1667 return pldm_xlate_errno(rc);
1668 }
1669
1670 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301671}
1672
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301673LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301674int decode_state_sensor_data(const uint8_t *sensor_data,
1675 size_t sensor_data_length, uint8_t *sensor_offset,
1676 uint8_t *event_state,
1677 uint8_t *previous_event_state)
1678{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301679 struct pldm_msgbuf _buf;
1680 struct pldm_msgbuf *buf = &_buf;
1681 int rc;
1682
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001683 if (sensor_data == NULL || sensor_offset == NULL ||
1684 event_state == NULL || previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301685 return PLDM_ERROR_INVALID_DATA;
1686 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301687
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301688 rc = pldm_msgbuf_init_errno(
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301689 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1690 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301691 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301692 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301693 }
1694
Andrew Jeffery66c77232024-04-24 11:42:02 +09301695 pldm_msgbuf_extract_p(buf, sensor_offset);
1696 pldm_msgbuf_extract_p(buf, event_state);
1697 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301698
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301699 rc = pldm_msgbuf_destroy_consumed(buf);
1700 if (rc) {
1701 return pldm_xlate_errno(rc);
1702 }
1703
1704 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301705}
1706
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301707LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301708int decode_numeric_sensor_data(const uint8_t *sensor_data,
1709 size_t sensor_data_length, uint8_t *event_state,
1710 uint8_t *previous_event_state,
1711 uint8_t *sensor_data_size,
1712 uint32_t *present_reading)
1713{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301714 struct pldm_msgbuf _buf;
1715 struct pldm_msgbuf *buf = &_buf;
1716 int rc;
1717
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03001718 if (sensor_data == NULL || sensor_data_size == NULL ||
1719 event_state == NULL || previous_event_state == NULL ||
1720 present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301721 return PLDM_ERROR_INVALID_DATA;
1722 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301723
1724 if (sensor_data_length >
1725 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301726 return PLDM_ERROR_INVALID_LENGTH;
1727 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301728
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301729 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301730 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1731 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301732 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301733 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301734 }
1735
Andrew Jeffery66c77232024-04-24 11:42:02 +09301736 pldm_msgbuf_extract_p(buf, event_state);
1737 pldm_msgbuf_extract_p(buf, previous_event_state);
1738 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301739 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301740 return pldm_xlate_errno(rc);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301741 }
1742
1743 /*
1744 * The implementation below is bonkers, but it's because the function
1745 * prototype is bonkers. The `present_reading` argument should have been
1746 * a tagged union.
1747 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301748 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301749 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1750 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301751 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301752 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301753 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301754 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301755 }
1756 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1757 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301758 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301759 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301760 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301761 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301762 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301763 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301764 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301765 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301766 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301767 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301768 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301769 }
1770 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301771 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301772 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301773 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301774 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301775 break;
1776 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301777 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1778 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301779 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301780 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301781 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301782 break;
1783 }
1784 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1785 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301786 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301787 *present_reading = (uint32_t)val;
1788 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301789 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301790 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301791 default:
1792 return PLDM_ERROR_INVALID_DATA;
1793 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301794
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301795 rc = pldm_msgbuf_destroy_consumed(buf);
1796 if (rc) {
1797 return pldm_xlate_errno(rc);
1798 }
1799
1800 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301801}
1802
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301803LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301804int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301805 const void *pdr_data, size_t pdr_data_length,
1806 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301807{
1808 struct pldm_msgbuf _buf;
1809 struct pldm_msgbuf *buf = &_buf;
1810 int rc;
1811
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301812 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1813 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301814 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301815 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301816 }
1817
Andrew Jeffery329176a2024-09-26 22:38:24 +09301818 rc = pldm_msgbuf_extract_value_pdr_hdr(
1819 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301820 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301821 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09301822 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301823 }
1824
Andrew Jeffery66c77232024-04-24 11:42:02 +09301825 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1826 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1827 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1828 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1829 pldm_msgbuf_extract(buf, pdr_value->container_id);
1830 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1831 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1832 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1833 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1834 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1835 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1836 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1837 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1838 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1839 pldm_msgbuf_extract(buf, pdr_value->rel);
1840 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1841 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301842
Andrew Jeffery66c77232024-04-24 11:42:02 +09301843 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301844 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301845 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301846 }
1847 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1848 return PLDM_ERROR_INVALID_DATA;
1849 }
1850
Andrew Jeffery66c77232024-04-24 11:42:02 +09301851 pldm_msgbuf_extract(buf, pdr_value->resolution);
1852 pldm_msgbuf_extract(buf, pdr_value->offset);
1853 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1854 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1855 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301856 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1857 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301858 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301859 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301860 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1861 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1862 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301863 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1864 &pdr_value->max_readable);
1865 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1866 &pdr_value->min_readable);
1867
Andrew Jeffery66c77232024-04-24 11:42:02 +09301868 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301869 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301870 return pldm_xlate_errno(rc);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301871 }
1872 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1873 return PLDM_ERROR_INVALID_DATA;
1874 }
1875
Andrew Jeffery66c77232024-04-24 11:42:02 +09301876 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301877 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301878 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301879 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301880 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301881 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301882 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301883 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301884 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301885 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301886 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301887 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301888 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301889 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301890 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301891 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301892 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301893 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301894 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301895
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301896 rc = pldm_msgbuf_destroy(buf);
1897 if (rc) {
1898 return pldm_xlate_errno(rc);
1899 }
1900
1901 return PLDM_SUCCESS;
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301902}
1903
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301904LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301905int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1906 uint16_t effecter_id,
1907 struct pldm_msg *msg)
1908{
1909 if (msg == NULL) {
1910 return PLDM_ERROR_INVALID_DATA;
1911 }
1912
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301913 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301914 header.msg_type = PLDM_REQUEST;
1915 header.instance = instance_id;
1916 header.pldm_type = PLDM_PLATFORM;
1917 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1918
1919 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1920 if (rc != PLDM_SUCCESS) {
1921 return rc;
1922 }
1923
1924 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301925 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301926 request->effecter_id = htole16(effecter_id);
1927
1928 return PLDM_SUCCESS;
1929}
1930
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301931LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301932int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301933 uint8_t instance_id, uint8_t completion_code,
1934 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1935 const uint8_t *pending_value, const uint8_t *present_value,
1936 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301937{
1938 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1939 return PLDM_ERROR_INVALID_DATA;
1940 }
1941
1942 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1943 return PLDM_ERROR_INVALID_DATA;
1944 }
1945
1946 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1947 return PLDM_ERROR_INVALID_DATA;
1948 }
1949
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301950 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301951 header.msg_type = PLDM_RESPONSE;
1952 header.instance = instance_id;
1953 header.pldm_type = PLDM_PLATFORM;
1954 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1955
1956 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1957 if (rc != PLDM_SUCCESS) {
1958 return rc;
1959 }
1960
1961 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301962 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301963
1964 response->completion_code = completion_code;
1965 response->effecter_data_size = effecter_data_size;
1966 response->effecter_oper_state = effecter_oper_state;
1967
1968 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1969 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1970 if (payload_length !=
1971 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1972 return PLDM_ERROR_INVALID_LENGTH;
1973 }
1974 response->pending_and_present_values[0] = *pending_value;
1975 response->pending_and_present_values[1] = *present_value;
1976
1977 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1978 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1979 if (payload_length !=
1980 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1981 return PLDM_ERROR_INVALID_LENGTH;
1982 }
1983 uint16_t val_pending = *(uint16_t *)pending_value;
1984 val_pending = htole16(val_pending);
1985 memcpy(response->pending_and_present_values, &val_pending,
1986 sizeof(uint16_t));
1987 uint16_t val_present = *(uint16_t *)present_value;
1988 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301989 memcpy((response->pending_and_present_values +
1990 sizeof(uint16_t)),
1991 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301992
1993 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1994 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1995 if (payload_length !=
1996 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1997 return PLDM_ERROR_INVALID_LENGTH;
1998 }
1999 uint32_t val_pending = *(uint32_t *)pending_value;
2000 val_pending = htole32(val_pending);
2001 memcpy(response->pending_and_present_values, &val_pending,
2002 sizeof(uint32_t));
2003 uint32_t val_present = *(uint32_t *)present_value;
2004 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302005 memcpy((response->pending_and_present_values +
2006 sizeof(uint32_t)),
2007 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09302008 }
2009 return PLDM_SUCCESS;
2010}
2011
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302012LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302013int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
2014 size_t payload_length,
2015 uint16_t *effecter_id)
2016{
Andrew Jefferydd265822023-04-13 22:42:44 +09302017 struct pldm_msgbuf _buf;
2018 struct pldm_msgbuf *buf = &_buf;
2019 int rc;
2020
Andrew Jeffery9c766792022-08-10 23:12:49 +09302021 if (msg == NULL || effecter_id == NULL) {
2022 return PLDM_ERROR_INVALID_DATA;
2023 }
2024
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302025 rc = pldm_msgbuf_init_errno(buf,
2026 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2027 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09302028 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302029 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302030 }
2031
Andrew Jeffery66c77232024-04-24 11:42:02 +09302032 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302033
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302034 rc = pldm_msgbuf_destroy_consumed(buf);
2035 if (rc) {
2036 return pldm_xlate_errno(rc);
2037 }
2038
2039 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302040}
2041
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302042LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302043int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2044 size_t payload_length,
2045 uint8_t *completion_code,
2046 uint8_t *effecter_data_size,
2047 uint8_t *effecter_oper_state,
2048 uint8_t *pending_value,
2049 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302050{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302051 struct pldm_msgbuf _buf;
2052 struct pldm_msgbuf *buf = &_buf;
2053 int rc;
2054
Andrew Jeffery9c766792022-08-10 23:12:49 +09302055 if (msg == NULL || effecter_data_size == NULL ||
2056 effecter_oper_state == NULL || pending_value == NULL ||
2057 present_value == NULL) {
2058 return PLDM_ERROR_INVALID_DATA;
2059 }
2060
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302061 rc = pldm_msgbuf_init_errno(
2062 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2063 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302064 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302065 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302066 }
2067
Andrew Jeffery66c77232024-04-24 11:42:02 +09302068 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302069 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302070 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302071 }
2072
Andrew Jeffery9c766792022-08-10 23:12:49 +09302073 if (PLDM_SUCCESS != *completion_code) {
2074 return PLDM_SUCCESS;
2075 }
2076
Andrew Jeffery66c77232024-04-24 11:42:02 +09302077 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302078 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302079 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302080 }
2081
Andrew Jeffery9c766792022-08-10 23:12:49 +09302082 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2083 return PLDM_ERROR_INVALID_DATA;
2084 }
2085
Andrew Jeffery66c77232024-04-24 11:42:02 +09302086 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302087 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302088 return pldm_xlate_errno(rc);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302089 }
2090
Andrew Jeffery9c766792022-08-10 23:12:49 +09302091 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
2092 return PLDM_ERROR_INVALID_DATA;
2093 }
2094
Andrew Jeffery99c03f32023-04-13 22:45:30 +09302095 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2096 pending_value);
2097 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2098 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302099
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302100 rc = pldm_msgbuf_destroy_consumed(buf);
2101 if (rc) {
2102 return pldm_xlate_errno(rc);
2103 }
2104
2105 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302106}
2107
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302108LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302109int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302110 uint8_t event_data_format, uint8_t number_of_change_records,
2111 const uint8_t *event_data_operations,
2112 const uint8_t *numbers_of_change_entries,
2113 const uint32_t *const *change_entries,
2114 struct pldm_pdr_repository_chg_event_data *event_data,
2115 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302116{
2117 if (event_data_operations == NULL ||
2118 numbers_of_change_entries == NULL || change_entries == NULL) {
2119 return PLDM_ERROR_INVALID_DATA;
2120 }
2121
2122 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302123 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302124
2125 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302126 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302127 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302128 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302129
2130 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302131 expected_size += sizeof(*change_entries[0]) *
2132 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302133 }
2134
2135 *actual_change_records_size = expected_size;
2136
2137 if (event_data == NULL) {
2138 return PLDM_SUCCESS;
2139 }
2140
2141 if (max_change_records_size < expected_size) {
2142 return PLDM_ERROR_INVALID_LENGTH;
2143 }
2144
2145 event_data->event_data_format = event_data_format;
2146 event_data->number_of_change_records = number_of_change_records;
2147
2148 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302149 (struct pldm_pdr_repository_change_record_data *)
2150 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302151
2152 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2153 record_data->event_data_operation = event_data_operations[i];
2154 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302155 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09302156
2157 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2158 ++j) {
2159 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302160 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302161 }
2162
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302163 record_data =
2164 (struct pldm_pdr_repository_change_record_data
2165 *)(record_data->change_entry +
2166 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302167 }
2168
2169 return PLDM_SUCCESS;
2170}
2171
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302172LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302173int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2174 size_t event_data_size,
2175 uint8_t *event_data_format,
2176 uint8_t *number_of_change_records,
2177 size_t *change_record_data_offset)
2178{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302179 struct pldm_msgbuf _buf;
2180 struct pldm_msgbuf *buf = &_buf;
2181 int rc;
2182
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002183 if (event_data == NULL || event_data_format == NULL ||
2184 number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302185 change_record_data_offset == NULL) {
2186 return PLDM_ERROR_INVALID_DATA;
2187 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302188
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302189 rc = pldm_msgbuf_init_errno(buf,
2190 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2191 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09302192 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302193 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302194 }
2195
Andrew Jeffery66c77232024-04-24 11:42:02 +09302196 pldm_msgbuf_extract_p(buf, event_data_format);
2197 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302198
Andrew Jeffery9c766792022-08-10 23:12:49 +09302199 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302200 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302201
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302202 rc = pldm_msgbuf_destroy(buf);
2203 if (rc) {
2204 return pldm_xlate_errno(rc);
2205 }
2206
2207 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302208}
2209
Thu Nguyenf874b382024-07-24 11:22:34 +00002210LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00002211int decode_pldm_message_poll_event_data(
2212 const void *event_data, size_t event_data_length,
2213 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07002214{
2215 struct pldm_msgbuf _buf;
2216 struct pldm_msgbuf *buf = &_buf;
2217 int rc;
2218
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002219 if (!event_data || !poll_event) {
Thu Nguyen7739d122024-07-26 11:36:39 +00002220 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07002221 }
2222
Thu Nguyen7739d122024-07-26 11:36:39 +00002223 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2224 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002225 if (rc) {
2226 return rc;
2227 }
2228
Thu Nguyen7739d122024-07-26 11:36:39 +00002229 pldm_msgbuf_extract(buf, poll_event->format_version);
2230 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07002231 if (rc) {
2232 return rc;
2233 }
2234
Thu Nguyen7739d122024-07-26 11:36:39 +00002235 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2236 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002237 }
2238
Thu Nguyen7739d122024-07-26 11:36:39 +00002239 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002240
2241 return pldm_msgbuf_destroy_consumed(buf);
2242}
2243
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302244LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00002245int encode_pldm_message_poll_event_data(
2246 const struct pldm_message_poll_event *poll_event, void *event_data,
2247 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07002248{
2249 struct pldm_msgbuf _buf;
2250 struct pldm_msgbuf *buf = &_buf;
2251 int rc;
2252
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002253 if (poll_event == NULL || event_data == NULL) {
2254 return -EINVAL;
2255 }
2256
Thu Nguyen7739d122024-07-26 11:36:39 +00002257 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2258 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07002259 }
2260
Thu Nguyen7739d122024-07-26 11:36:39 +00002261 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2262 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07002263 if (rc) {
2264 return rc;
2265 }
Thu Nguyen7739d122024-07-26 11:36:39 +00002266 pldm_msgbuf_insert(buf, poll_event->format_version);
2267 pldm_msgbuf_insert(buf, poll_event->event_id);
2268 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07002269
Thu Nguyen7739d122024-07-26 11:36:39 +00002270 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07002271}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302272
2273LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302274int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302275 const uint8_t *change_record_data, size_t change_record_data_size,
2276 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
2277 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302278{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302279 struct pldm_msgbuf _buf;
2280 struct pldm_msgbuf *buf = &_buf;
2281 int rc;
2282
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002283 if (change_record_data == NULL || event_data_operation == NULL ||
2284 number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09302285 change_entry_data_offset == NULL) {
2286 return PLDM_ERROR_INVALID_DATA;
2287 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302288
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302289 rc = pldm_msgbuf_init_errno(
2290 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2291 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09302292 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302293 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302294 }
2295
Andrew Jeffery66c77232024-04-24 11:42:02 +09302296 pldm_msgbuf_extract_p(buf, event_data_operation);
2297 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302298
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302299 *change_entry_data_offset = sizeof(*event_data_operation) +
2300 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302301
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302302 rc = pldm_msgbuf_destroy(buf);
2303 if (rc) {
2304 return pldm_xlate_errno(rc);
2305 }
2306
2307 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302308}
2309
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302310LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302311int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2312 uint8_t rearm_event_state,
2313 struct pldm_msg *msg)
2314{
2315 if (msg == NULL) {
2316 return PLDM_ERROR_INVALID_DATA;
2317 }
2318
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302319 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302320 header.msg_type = PLDM_REQUEST;
2321 header.instance = instance_id;
2322 header.pldm_type = PLDM_PLATFORM;
2323 header.command = PLDM_GET_SENSOR_READING;
2324
2325 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2326 if (rc != PLDM_SUCCESS) {
2327 return rc;
2328 }
2329
2330 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302331 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302332
2333 request->sensor_id = htole16(sensor_id);
2334 request->rearm_event_state = rearm_event_state;
2335
2336 return PLDM_SUCCESS;
2337}
2338
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302339LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302340int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302341 const struct pldm_msg *msg, size_t payload_length,
2342 uint8_t *completion_code, uint8_t *sensor_data_size,
2343 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2344 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2345 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302346{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302347 struct pldm_msgbuf _buf;
2348 struct pldm_msgbuf *buf = &_buf;
2349 int rc;
2350
Andrew Jeffery9c766792022-08-10 23:12:49 +09302351 if (msg == NULL || completion_code == NULL ||
2352 sensor_data_size == NULL || sensor_operational_state == NULL ||
2353 sensor_event_message_enable == NULL || present_state == NULL ||
2354 previous_state == NULL || event_state == NULL ||
2355 present_reading == NULL) {
2356 return PLDM_ERROR_INVALID_DATA;
2357 }
2358
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302359 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2360 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302361 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302362 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302363 }
2364
Andrew Jeffery66c77232024-04-24 11:42:02 +09302365 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302366 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302367 return pldm_xlate_errno(rc);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302368 }
2369
Andrew Jeffery9c766792022-08-10 23:12:49 +09302370 if (PLDM_SUCCESS != *completion_code) {
2371 return PLDM_SUCCESS;
2372 }
2373
Andrew Jeffery66c77232024-04-24 11:42:02 +09302374 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302375 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302376 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302377 }
2378
Andrew Jeffery840b1402023-04-13 23:54:44 +09302379 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302380 return PLDM_ERROR_INVALID_DATA;
2381 }
2382
Andrew Jeffery66c77232024-04-24 11:42:02 +09302383 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2384 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2385 pldm_msgbuf_extract_p(buf, present_state);
2386 pldm_msgbuf_extract_p(buf, previous_state);
2387 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302388
Andrew Jeffery840b1402023-04-13 23:54:44 +09302389 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2390 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302391
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302392 rc = pldm_msgbuf_destroy_consumed(buf);
2393 if (rc) {
2394 return pldm_xlate_errno(rc);
2395 }
2396
2397 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302398}
2399
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302400LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302401int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2402 uint8_t sensor_data_size,
2403 uint8_t sensor_operational_state,
2404 uint8_t sensor_event_message_enable,
2405 uint8_t present_state,
2406 uint8_t previous_state, uint8_t event_state,
2407 const uint8_t *present_reading,
2408 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302409{
2410 if (msg == NULL || present_reading == NULL) {
2411 return PLDM_ERROR_INVALID_DATA;
2412 }
2413
2414 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2415 return PLDM_ERROR_INVALID_DATA;
2416 }
2417
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302418 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302419 header.msg_type = PLDM_RESPONSE;
2420 header.instance = instance_id;
2421 header.pldm_type = PLDM_PLATFORM;
2422 header.command = PLDM_GET_SENSOR_READING;
2423
2424 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2425 if (rc != PLDM_SUCCESS) {
2426 return rc;
2427 }
2428
2429 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302430 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302431
2432 response->completion_code = completion_code;
2433 response->sensor_data_size = sensor_data_size;
2434 response->sensor_operational_state = sensor_operational_state;
2435 response->sensor_event_message_enable = sensor_event_message_enable;
2436 response->present_state = present_state;
2437 response->previous_state = previous_state;
2438 response->event_state = event_state;
2439
2440 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2441 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2442 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2443 return PLDM_ERROR_INVALID_LENGTH;
2444 }
2445 response->present_reading[0] = *present_reading;
2446
2447 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2448 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2449 if (payload_length !=
2450 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2451 return PLDM_ERROR_INVALID_LENGTH;
2452 }
2453 uint16_t val = *(uint16_t *)present_reading;
2454 val = htole16(val);
2455 memcpy(response->present_reading, &val, 2);
2456
2457 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2458 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2459 if (payload_length !=
2460 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2461 return PLDM_ERROR_INVALID_LENGTH;
2462 }
2463 uint32_t val = *(uint32_t *)present_reading;
2464 val = htole32(val);
2465 memcpy(response->present_reading, &val, 4);
2466 }
2467
2468 return PLDM_SUCCESS;
2469}
2470
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302471LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302472int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2473 size_t payload_length, uint16_t *sensor_id,
2474 uint8_t *rearm_event_state)
2475{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302476 struct pldm_msgbuf _buf;
2477 struct pldm_msgbuf *buf = &_buf;
2478 int rc;
2479
Andrew Jeffery9c766792022-08-10 23:12:49 +09302480 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2481 return PLDM_ERROR_INVALID_DATA;
2482 }
2483
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302484 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2485 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302486 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302487 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302488 }
2489
Andrew Jeffery66c77232024-04-24 11:42:02 +09302490 pldm_msgbuf_extract_p(buf, sensor_id);
2491 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302492
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302493 rc = pldm_msgbuf_destroy(buf);
2494 if (rc) {
2495 return pldm_xlate_errno(rc);
2496 }
2497
2498 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302499}
2500
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302501LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302502int encode_set_event_receiver_req(uint8_t instance_id,
2503 uint8_t event_message_global_enable,
2504 uint8_t transport_protocol_type,
2505 uint8_t event_receiver_address_info,
2506 uint16_t heartbeat_timer,
2507 struct pldm_msg *msg)
2508{
2509 if (msg == NULL) {
2510 return PLDM_ERROR_INVALID_DATA;
2511 }
2512
2513 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2514 return PLDM_ERROR_INVALID_DATA;
2515 }
2516
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302517 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302518 header.msg_type = PLDM_REQUEST;
2519 header.instance = instance_id;
2520 header.pldm_type = PLDM_PLATFORM;
2521 header.command = PLDM_SET_EVENT_RECEIVER;
2522
2523 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2524 if (rc != PLDM_SUCCESS) {
2525 return rc;
2526 }
2527
2528 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302529 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302530 request->event_message_global_enable = event_message_global_enable;
2531
2532 request->transport_protocol_type = transport_protocol_type;
2533 request->event_receiver_address_info = event_receiver_address_info;
2534
2535 if (event_message_global_enable ==
2536 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2537 if (heartbeat_timer == 0) {
2538 return PLDM_ERROR_INVALID_DATA;
2539 }
2540 request->heartbeat_timer = htole16(heartbeat_timer);
2541 }
2542
2543 return PLDM_SUCCESS;
2544}
2545
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302546LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302547int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2548 size_t payload_length,
2549 uint8_t *completion_code)
2550{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302551 struct pldm_msgbuf _buf;
2552 struct pldm_msgbuf *buf = &_buf;
2553 int rc;
2554
Andrew Jeffery9c766792022-08-10 23:12:49 +09302555 if (msg == NULL || completion_code == NULL) {
2556 return PLDM_ERROR_INVALID_DATA;
2557 }
2558
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302559 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2560 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302561 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302562 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302563 }
2564
Andrew Jeffery66c77232024-04-24 11:42:02 +09302565 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302566
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302567 rc = pldm_msgbuf_destroy(buf);
2568 if (rc) {
2569 return pldm_xlate_errno(rc);
2570 }
2571
2572 return PLDM_SUCCESS;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302573}
2574
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302575LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302576int decode_set_event_receiver_req(const struct pldm_msg *msg,
2577 size_t payload_length,
2578 uint8_t *event_message_global_enable,
2579 uint8_t *transport_protocol_type,
2580 uint8_t *event_receiver_address_info,
2581 uint16_t *heartbeat_timer)
2582
2583{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302584 struct pldm_msgbuf _buf;
2585 struct pldm_msgbuf *buf = &_buf;
2586 int rc;
2587
Andrew Jeffery9c766792022-08-10 23:12:49 +09302588 if (msg == NULL || event_message_global_enable == NULL ||
2589 transport_protocol_type == NULL ||
2590 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2591 return PLDM_ERROR_INVALID_DATA;
2592 }
2593
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302594 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2595 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302596 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302597 return pldm_xlate_errno(rc);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302598 }
2599
Andrew Jeffery66c77232024-04-24 11:42:02 +09302600 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2601 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2602 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
Andrew Jeffery2332e052024-10-08 13:52:34 +10302603 pldm_msgbuf_extract_p(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302604
Andrew Jeffery9667f582023-04-14 00:39:21 +09302605 rc = pldm_msgbuf_destroy(buf);
2606 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302607 return pldm_xlate_errno(rc);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302608 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302609
Andrew Jeffery9c766792022-08-10 23:12:49 +09302610 if ((*event_message_global_enable ==
2611 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2612 (*heartbeat_timer == 0)) {
2613 return PLDM_ERROR_INVALID_DATA;
2614 }
2615
Andrew Jeffery9c766792022-08-10 23:12:49 +09302616 return PLDM_SUCCESS;
2617}
2618
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302619LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302620int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2621 struct pldm_msg *msg)
2622
2623{
2624 if (msg == NULL) {
2625 return PLDM_ERROR_INVALID_DATA;
2626 }
2627
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302628 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302629 header.instance = instance_id;
2630 header.msg_type = PLDM_RESPONSE;
2631 header.pldm_type = PLDM_PLATFORM;
2632 header.command = PLDM_SET_EVENT_RECEIVER;
2633
2634 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2635 if (rc != PLDM_SUCCESS) {
2636 return rc;
2637 }
2638
2639 msg->payload[0] = completion_code;
2640
2641 return PLDM_SUCCESS;
2642}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002643
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302644LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002645int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2646 uint8_t format_version,
2647 uint8_t transfer_operation_flag,
2648 uint32_t data_transfer_handle,
2649 uint16_t event_id_to_acknowledge,
2650 struct pldm_msg *msg,
2651 size_t payload_length)
2652{
2653 struct pldm_msgbuf _buf;
2654 struct pldm_msgbuf *buf = &_buf;
2655 int rc;
2656
2657 if (msg == NULL) {
2658 return PLDM_ERROR_INVALID_DATA;
2659 }
2660
Thu Nguyen387b10f2024-09-24 11:33:16 +00002661 rc = pldm_platform_poll_for_platform_event_message_validate(
2662 transfer_operation_flag, event_id_to_acknowledge);
2663 if (rc < 0) {
2664 return PLDM_ERROR_INVALID_DATA;
2665 }
2666
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302667 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002668 header.msg_type = PLDM_REQUEST;
2669 header.instance = instance_id;
2670 header.pldm_type = PLDM_PLATFORM;
2671 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2672
2673 rc = pack_pldm_header(&header, &(msg->hdr));
2674 if (rc != PLDM_SUCCESS) {
2675 return rc;
2676 }
2677
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302678 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302679 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2680 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002681 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302682 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002683 }
2684
2685 pldm_msgbuf_insert(buf, format_version);
2686 pldm_msgbuf_insert(buf, transfer_operation_flag);
2687 pldm_msgbuf_insert(buf, data_transfer_handle);
2688 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2689
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302690 rc = pldm_msgbuf_destroy(buf);
2691 if (rc) {
2692 return pldm_xlate_errno(rc);
2693 }
2694
2695 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002696}
2697
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302698LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002699int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302700 const struct pldm_msg *msg, size_t payload_length,
2701 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2702 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2703 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2704 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002705{
2706 struct pldm_msgbuf _buf;
2707 struct pldm_msgbuf *buf = &_buf;
2708 int rc;
2709
2710 if (msg == NULL || completion_code == NULL || tid == NULL ||
2711 event_id == NULL || next_data_transfer_handle == NULL ||
2712 transfer_flag == NULL || event_class == NULL ||
2713 event_data_size == NULL || event_data == NULL ||
2714 event_data_integrity_checksum == NULL) {
2715 return PLDM_ERROR_INVALID_DATA;
2716 }
2717
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302718 rc = pldm_msgbuf_init_errno(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302719 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2720 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002721 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302722 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002723 }
2724
Andrew Jeffery66c77232024-04-24 11:42:02 +09302725 rc = pldm_msgbuf_extract_p(buf, completion_code);
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 (PLDM_SUCCESS != *completion_code) {
2730 return *completion_code;
2731 }
2732
Andrew Jeffery66c77232024-04-24 11:42:02 +09302733 pldm_msgbuf_extract_p(buf, tid);
2734 rc = pldm_msgbuf_extract_p(buf, event_id);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002735 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302736 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002737 }
2738 if ((*event_id == 0) || (*event_id == 0xffff)) {
2739 return PLDM_SUCCESS;
2740 }
2741
Andrew Jeffery66c77232024-04-24 11:42:02 +09302742 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2743 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002744 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302745 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002746 }
2747
Andrew Jeffery66c77232024-04-24 11:42:02 +09302748 pldm_msgbuf_extract_p(buf, event_class);
2749 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002750 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302751 return pldm_xlate_errno(rc);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002752 }
2753 if (*event_data_size > payload_length) {
2754 return PLDM_ERROR_INVALID_DATA;
2755 }
2756
2757 if (*event_data_size > 0) {
2758 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2759 }
2760
2761 if (*transfer_flag == PLDM_END ||
2762 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302763 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002764 }
2765
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302766 rc = pldm_msgbuf_destroy_consumed(buf);
2767 if (rc) {
2768 return pldm_xlate_errno(rc);
2769 }
2770
2771 return PLDM_SUCCESS;
Thu Nguyen159a98b2022-11-02 10:00:10 +07002772}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002773
2774LIBPLDM_ABI_TESTING
2775int decode_numeric_effecter_pdr_data(
2776 const void *pdr_data, size_t pdr_data_length,
2777 struct pldm_numeric_effecter_value_pdr *pdr_value)
2778{
2779 struct pldm_msgbuf _buf;
2780 struct pldm_msgbuf *buf = &_buf;
2781 struct pldm_value_pdr_hdr hdr;
2782 int rc;
2783
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03002784 if (!pdr_data || !pdr_value) {
2785 return PLDM_ERROR_INVALID_DATA;
2786 }
2787
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302788 rc = pldm_msgbuf_init_errno(buf,
2789 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2790 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002791 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302792 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002793 }
2794
Andrew Jeffery329176a2024-09-26 22:38:24 +09302795 rc = pldm_msgbuf_extract_value_pdr_hdr(
2796 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
Thu Nguyend4878cd2023-11-09 10:18:33 +07002797 pdr_data_length);
2798 if (rc) {
Andrew Jeffery329176a2024-09-26 22:38:24 +09302799 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002800 }
2801
2802 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2803
2804 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2805 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2806 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2807 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2808 pldm_msgbuf_extract(buf, pdr_value->container_id);
2809 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2810 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2811 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2812 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2813 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2814 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2815 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2816 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2817 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2818 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2819 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2820 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2821
2822 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2823 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302824 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002825 }
2826 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2827 return PLDM_ERROR_INVALID_DATA;
2828 }
2829
2830 pldm_msgbuf_extract(buf, pdr_value->resolution);
2831 pldm_msgbuf_extract(buf, pdr_value->offset);
2832 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2833 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2834 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2835 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2836 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2837 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2838 pdr_value->max_settable);
2839 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2840 pdr_value->min_settable);
2841
2842 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2843 if (rc) {
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302844 return pldm_xlate_errno(rc);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002845 }
2846 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2847 return PLDM_ERROR_INVALID_DATA;
2848 }
2849
2850 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2851 pldm_msgbuf_extract_range_field_format(
2852 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2853 pldm_msgbuf_extract_range_field_format(
2854 buf, pdr_value->range_field_format, pdr_value->normal_max);
2855 pldm_msgbuf_extract_range_field_format(
2856 buf, pdr_value->range_field_format, pdr_value->normal_min);
2857 pldm_msgbuf_extract_range_field_format(
2858 buf, pdr_value->range_field_format, pdr_value->rated_max);
2859 pldm_msgbuf_extract_range_field_format(
2860 buf, pdr_value->range_field_format, pdr_value->rated_min);
2861
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302862 rc = pldm_msgbuf_destroy_consumed(buf);
2863 if (rc) {
2864 return pldm_xlate_errno(rc);
2865 }
2866
2867 return PLDM_SUCCESS;
Thu Nguyend4878cd2023-11-09 10:18:33 +07002868}
Tal Yacobia6fa5552024-05-05 16:57:38 +03002869
Tal Yacobide67ab62024-05-30 22:36:50 +03002870LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002871int encode_get_state_effecter_states_req(uint8_t instance_id,
2872 uint16_t effecter_id,
2873 struct pldm_msg *msg,
2874 size_t payload_length)
2875{
2876 struct pldm_msgbuf _buf;
2877 struct pldm_msgbuf *buf = &_buf;
2878 int rc;
2879
2880 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002881 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002882 }
2883
2884 struct pldm_header_info header = { 0 };
2885 header.msg_type = PLDM_REQUEST;
2886 header.instance = instance_id;
2887 header.pldm_type = PLDM_PLATFORM;
2888 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2889
Tal Yacobif490a382024-05-31 09:57:36 +03002890 rc = pack_pldm_header_errno(&header, &msg->hdr);
2891 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002892 return rc;
2893 }
2894
Tal Yacobif490a382024-05-31 09:57:36 +03002895 rc = pldm_msgbuf_init_errno(buf,
2896 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2897 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002898 if (rc) {
2899 return rc;
2900 }
2901
2902 pldm_msgbuf_insert(buf, effecter_id);
2903
2904 return pldm_msgbuf_destroy_consumed(buf);
2905}
2906
Tal Yacobide67ab62024-05-30 22:36:50 +03002907LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002908int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
2909 size_t payload_length,
2910 uint16_t *effecter_id)
2911{
2912 struct pldm_msgbuf _buf;
2913 struct pldm_msgbuf *buf = &_buf;
2914 int rc;
2915
2916 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002917 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002918 }
2919
Tal Yacobif490a382024-05-31 09:57:36 +03002920 rc = pldm_msgbuf_init_errno(
2921 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2922 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002923 if (rc) {
2924 return rc;
2925 }
2926
2927 pldm_msgbuf_extract_p(buf, effecter_id);
2928
2929 return pldm_msgbuf_destroy_consumed(buf);
2930}
2931
Tal Yacobide67ab62024-05-30 22:36:50 +03002932LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002933int decode_get_state_effecter_states_resp(
2934 const struct pldm_msg *msg, size_t payload_length,
2935 struct pldm_get_state_effecter_states_resp *resp)
2936{
2937 struct pldm_msgbuf _buf;
2938 struct pldm_msgbuf *buf = &_buf;
2939 get_effecter_state_field *field;
2940 int rc;
2941 int i;
2942
2943 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002944 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002945 }
2946
Tal Yacobif490a382024-05-31 09:57:36 +03002947 rc = pldm_msgbuf_init_errno(
2948 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2949 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002950 if (rc) {
2951 return rc;
2952 }
2953
2954 rc = pldm_msgbuf_extract(buf, resp->completion_code);
2955 if (rc) {
2956 return rc;
2957 }
2958
2959 if (PLDM_SUCCESS != resp->completion_code) {
Tal Yacobif490a382024-05-31 09:57:36 +03002960 return 0;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002961 }
2962
2963 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
2964 if (rc) {
2965 return rc;
2966 }
2967
2968 uint8_t comp_effecter_count = resp->comp_effecter_count;
2969
2970 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2971 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002972 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002973 }
2974
2975 for (i = 0, field = resp->field; i < comp_effecter_count;
2976 i++, field++) {
2977 pldm_msgbuf_extract(buf, field->effecter_op_state);
2978 pldm_msgbuf_extract(buf, field->pending_state);
2979 pldm_msgbuf_extract(buf, field->present_state);
2980 }
2981
2982 return pldm_msgbuf_destroy_consumed(buf);
2983}
2984
Tal Yacobide67ab62024-05-30 22:36:50 +03002985LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002986int encode_get_state_effecter_states_resp(
2987 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
2988 struct pldm_msg *msg, size_t payload_length)
2989{
2990 struct pldm_msgbuf _buf;
2991 struct pldm_msgbuf *buf = &_buf;
2992 get_effecter_state_field *field;
2993 int rc;
2994 int i;
2995
2996 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002997 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002998 }
2999
3000 uint8_t comp_effecter_count = resp->comp_effecter_count;
3001
3002 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
3003 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03003004 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03003005 }
3006
3007 struct pldm_header_info header = { 0 };
3008 header.msg_type = PLDM_RESPONSE;
3009 header.instance = instance_id;
3010 header.pldm_type = PLDM_PLATFORM;
3011 header.command = PLDM_GET_STATE_EFFECTER_STATES;
3012
Tal Yacobif490a382024-05-31 09:57:36 +03003013 rc = pack_pldm_header_errno(&header, &msg->hdr);
3014 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03003015 return rc;
3016 }
3017
Tal Yacobif490a382024-05-31 09:57:36 +03003018 rc = pldm_msgbuf_init_errno(
3019 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3020 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03003021 if (rc) {
3022 return rc;
3023 }
3024
3025 pldm_msgbuf_insert(buf, resp->completion_code);
3026 pldm_msgbuf_insert(buf, comp_effecter_count);
3027
3028 for (i = 0, field = resp->field; i < comp_effecter_count;
3029 i++, field++) {
3030 pldm_msgbuf_insert(buf, field->effecter_op_state);
3031 pldm_msgbuf_insert(buf, field->pending_state);
3032 pldm_msgbuf_insert(buf, field->present_state);
3033 }
3034
3035 return pldm_msgbuf_destroy_consumed(buf);
3036}
Thu Nguyendacfa352024-06-22 09:53:15 +00003037
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003038LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003039int decode_entity_auxiliary_names_pdr(
3040 const void *data, size_t data_length,
3041 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3042{
3043 struct pldm_msgbuf _buf;
3044 struct pldm_msgbuf *buf = &_buf;
3045 struct pldm_msgbuf _src;
3046 struct pldm_msgbuf *src = &_src;
3047 struct pldm_msgbuf _dst;
3048 struct pldm_msgbuf *dst = &_dst;
3049 size_t names_len = 0;
3050 void *names = NULL;
3051 int rc;
3052 int i;
3053
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003054 if (!data || !pdr) {
3055 return -EINVAL;
3056 }
3057
Thu Nguyendacfa352024-06-22 09:53:15 +00003058 /*
3059 * Alignment of auxiliary_name_data is an invariant as we statically assert
3060 * its behaviour in the header.
3061 */
3062 assert(!((uintptr_t)pdr->auxiliary_name_data &
3063 (alignof(pldm_utf16be) - 1)));
3064
3065 /* Reject any lengths that are obviously invalid */
3066 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3067 return -EINVAL;
3068 }
3069
3070 rc = pldm_msgbuf_init_errno(
3071 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3072 data_length);
3073 if (rc) {
3074 return rc;
3075 }
3076
Andrew Jeffery329176a2024-09-26 22:38:24 +09303077 rc = pldm_msgbuf_extract_value_pdr_hdr(
3078 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
Thu Nguyendacfa352024-06-22 09:53:15 +00003079 data_length);
3080 if (rc) {
3081 return rc;
3082 }
3083
3084 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3085 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3086 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3087 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3088 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3089 if (rc < 0) {
3090 return rc;
3091 }
3092
3093 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3094 if (rc < 0) {
3095 return rc;
3096 }
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +03003097 assert(names);
Thu Nguyendacfa352024-06-22 09:53:15 +00003098
3099 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3100
3101 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3102 pdr->auxiliary_name_data,
3103 pdr->auxiliary_name_data_size);
3104 if (rc < 0) {
3105 return rc;
3106 }
3107
3108 /*
3109 * Below we do two passes over the same region. This is to first pack the
3110 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3111 * to maintain appropriate alignment.
3112 */
3113
3114 /* Initialise for the first pass to extract the UTF16-BE name strings */
3115 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3116 if (rc < 0) {
3117 return rc;
3118 }
3119
3120 for (i = 0; i < pdr->name_string_count; i++) {
3121 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003122 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3123 if (rc) {
3124 return rc;
3125 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003126 }
3127
3128 rc = pldm_msgbuf_destroy_consumed(src);
3129 if (rc < 0) {
3130 return rc;
3131 }
3132
3133 /* Reinitialise for the second pass to extract the ASCII tag strings */
3134 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3135 if (rc < 0) {
3136 return rc;
3137 }
3138
3139 for (i = 0; i < pdr->name_string_count; i++) {
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003140 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3141 if (rc) {
3142 return rc;
3143 }
Thu Nguyendacfa352024-06-22 09:53:15 +00003144 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3145 }
3146
3147 if ((rc = pldm_msgbuf_destroy(dst)) ||
3148 (rc = pldm_msgbuf_destroy(src)) ||
3149 (rc = pldm_msgbuf_destroy(buf))) {
3150 return rc;
3151 }
3152
3153 return 0;
3154}
3155
Thu Nguyen43cb4b52024-07-16 05:45:27 +00003156LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00003157int decode_pldm_entity_auxiliary_names_pdr_index(
3158 struct pldm_entity_auxiliary_names_pdr *pdr)
3159{
3160 struct pldm_msgbuf _buf;
3161 struct pldm_msgbuf *buf = &_buf;
3162 int rc;
3163 int i;
3164
3165 if (!pdr) {
3166 return -EINVAL;
3167 }
3168
3169 if (pdr->name_string_count == 0 && pdr->names) {
3170 return -EINVAL;
3171 }
3172
3173 if (pdr->name_string_count > 0 && !pdr->names) {
3174 return -EINVAL;
3175 }
3176
3177 if (pdr->name_string_count == 0) {
3178 return 0;
3179 }
3180
3181 /*
3182 * Minimum size is one NUL for each member of each entry
3183 *
3184 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3185 * states the following:
3186 *
3187 * > A null-terminated ISO646 ASCII string ...
3188 * >
3189 * > special value: null string = 0x0000 = unspecified.
3190 *
3191 * Until proven otherwise we will assume the "0x0000" is a
3192 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3193 * represented by a single byte.
3194 */
3195 rc = pldm_msgbuf_init_errno(
3196 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3197 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3198 if (rc) {
3199 return rc;
3200 }
3201
3202 for (i = 0; i < pdr->name_string_count; i++) {
3203 void *loc = NULL;
3204 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3205 pdr->names[i].name = loc;
3206 }
3207
3208 for (i = 0; i < pdr->name_string_count; i++) {
3209 void *loc = NULL;
3210 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3211 pdr->names[i].tag = loc;
3212 }
3213
3214 return pldm_msgbuf_destroy_consumed(buf);
3215}
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003216
Thu Nguyen3559aa12024-08-29 00:13:38 +00003217LIBPLDM_ABI_STABLE
Thu Nguyen02903032024-09-03 06:39:50 +00003218int decode_pldm_platform_cper_event(const void *event_data,
3219 size_t event_data_length,
3220 struct pldm_platform_cper_event *cper_event,
3221 size_t cper_event_length)
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003222{
3223 struct pldm_msgbuf _buf;
3224 struct pldm_msgbuf *buf = &_buf;
3225 int rc;
3226
3227 if (!cper_event || !event_data) {
3228 return -EINVAL;
3229 }
3230
3231 if (cper_event_length < sizeof(*cper_event)) {
3232 return -EINVAL;
3233 }
3234
3235 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3236 event_data, event_data_length);
3237 if (rc) {
3238 return rc;
3239 }
3240
3241 pldm_msgbuf_extract(buf, cper_event->format_version);
3242 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3243 if (rc) {
3244 return rc;
3245 }
3246 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3247 cper_event->format_type !=
3248 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3249 return -EPROTO;
3250 }
3251
3252 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3253 if (rc) {
3254 return rc;
3255 }
3256
3257 if (cper_event->event_data_length >
3258 (cper_event_length - sizeof(*cper_event))) {
3259 return -EOVERFLOW;
3260 }
3261
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00003262 rc = pldm_msgbuf_extract_array_uint8(
3263 buf, cper_event->event_data_length, cper_event->event_data,
3264 cper_event_length - sizeof(*cper_event));
3265 if (rc) {
3266 return rc;
3267 }
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003268
3269 return pldm_msgbuf_destroy_consumed(buf);
3270}
3271
Thu Nguyen3559aa12024-08-29 00:13:38 +00003272LIBPLDM_ABI_STABLE
Thu Nguyena5d18dc2024-08-07 08:29:34 +00003273uint8_t *
3274pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3275{
3276 return event->event_data;
3277}