blob: f826f3cac03d5f8da5a8b20783d062411830ad78 [file] [log] [blame]
Patrick Williams691668f2023-11-01 08:19:10 -05001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
Tal Yacobif490a382024-05-31 09:57:36 +03002#include "dsp/base.h"
Andrew Jeffery7992eb82023-04-06 16:13:53 +09303#include "msgbuf.h"
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10304#include "msgbuf/platform.h"
5
6#include <libpldm/base.h>
7#include <libpldm/platform.h>
8#include <libpldm/pldm_types.h>
9
Andrew Jeffery9c766792022-08-10 23:12:49 +093010#include <endian.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053011#include <stdint.h>
Thu Nguyen159a98b2022-11-02 10:00:10 +070012#include <stdlib.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093013#include <string.h>
Thu Nguyendacfa352024-06-22 09:53:15 +000014#include <uchar.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093015
Andrew Jeffery7992eb82023-04-06 16:13:53 +093016static int pldm_platform_pdr_hdr_validate(struct pldm_value_pdr_hdr *ctx,
17 size_t lower, size_t upper)
18{
19 if (ctx->length + sizeof(*ctx) < lower) {
20 return PLDM_ERROR_INVALID_LENGTH;
21 }
22
23 if (ctx->length > upper) {
24 return PLDM_ERROR_INVALID_LENGTH;
25 }
26
27 return PLDM_SUCCESS;
28}
Andrew Jeffery9c766792022-08-10 23:12:49 +093029
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093030LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093031int encode_state_effecter_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093032 struct pldm_state_effecter_pdr *const effecter,
33 const size_t allocation_size,
34 const struct state_effecter_possible_states *const possible_states,
35 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093036{
37 // Encode possible states
38
39 size_t calculated_possible_states_size = 0;
40
41 {
42 char *states_ptr = (char *)possible_states;
43 char *const begin_states_ptr = states_ptr;
44
45 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
46 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093047 (struct state_effecter_possible_states *)
48 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093049
50 HTOLE16(states->state_set_id);
51
52 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093053 (sizeof(*states) - sizeof(states->states) +
54 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093055 }
56
57 calculated_possible_states_size = states_ptr - begin_states_ptr;
58 }
59
60 // Check lengths
61
62 if (possible_states_size != calculated_possible_states_size) {
63 *actual_size = 0;
64 return PLDM_ERROR;
65 }
66
67 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093068 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
69 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093070
71 if (allocation_size < *actual_size) {
72 *actual_size = 0;
73 return PLDM_ERROR_INVALID_LENGTH;
74 }
75
76 // Encode rest of PDR
77
78 effecter->hdr.version = 1;
79 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
80 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
81
82 memcpy(effecter->possible_states, possible_states,
83 possible_states_size);
84
85 // Convert effecter PDR body
86 HTOLE16(effecter->terminus_handle);
87 HTOLE16(effecter->effecter_id);
88 HTOLE16(effecter->entity_type);
89 HTOLE16(effecter->entity_instance);
90 HTOLE16(effecter->container_id);
91 HTOLE16(effecter->effecter_semantic_id);
92
93 // Convert header
94 HTOLE32(effecter->hdr.record_handle);
95 HTOLE16(effecter->hdr.record_change_num);
96 HTOLE16(effecter->hdr.length);
97
98 return PLDM_SUCCESS;
99}
100
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930101LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930102int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930103 struct pldm_state_sensor_pdr *const sensor,
104 const size_t allocation_size,
105 const struct state_sensor_possible_states *const possible_states,
106 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930107{
108 // Encode possible states
109
110 size_t calculated_possible_states_size = 0;
111
112 {
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930113 char *states_ptr = (char *)possible_states;
114 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930115
116 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
117 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930118 (struct state_sensor_possible_states *)
119 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930120
121 HTOLE16(states->state_set_id);
122
123 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930124 (sizeof(*states) - sizeof(states->states) +
125 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930126 }
127
128 calculated_possible_states_size = states_ptr - begin_states_ptr;
129 }
130
131 // Check lengths
132
133 if (possible_states_size != calculated_possible_states_size) {
134 *actual_size = 0;
135 return PLDM_ERROR;
136 }
137
138 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
139 possible_states_size - sizeof(sensor->possible_states));
140
141 if (allocation_size < *actual_size) {
142 *actual_size = 0;
143 return PLDM_ERROR_INVALID_LENGTH;
144 }
145
146 // Encode rest of PDR
147
148 sensor->hdr.version = 1;
149 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
150 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
151
152 memcpy(sensor->possible_states, possible_states, possible_states_size);
153
154 // Convert sensor PDR body
155 HTOLE16(sensor->terminus_handle);
156 HTOLE16(sensor->sensor_id);
157 HTOLE16(sensor->entity_type);
158 HTOLE16(sensor->entity_instance);
159 HTOLE16(sensor->container_id);
160
161 // Convert header
162 HTOLE32(sensor->hdr.record_handle);
163 HTOLE16(sensor->hdr.record_change_num);
164 HTOLE16(sensor->hdr.length);
165
166 return PLDM_SUCCESS;
167}
168
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930169LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930170int encode_set_state_effecter_states_resp(uint8_t instance_id,
171 uint8_t completion_code,
172 struct pldm_msg *msg)
173{
174 if (msg == NULL) {
175 return PLDM_ERROR_INVALID_DATA;
176 }
177
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930178 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930179 header.msg_type = PLDM_RESPONSE;
180 header.instance = instance_id;
181 header.pldm_type = PLDM_PLATFORM;
182 header.command = PLDM_SET_STATE_EFFECTER_STATES;
183
184 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
185 if (rc != PLDM_SUCCESS) {
186 return rc;
187 }
188
189 msg->payload[0] = completion_code;
190
191 return PLDM_SUCCESS;
192}
193
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930194LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930195int encode_set_state_effecter_states_req(uint8_t instance_id,
196 uint16_t effecter_id,
197 uint8_t comp_effecter_count,
198 set_effecter_state_field *field,
199 struct pldm_msg *msg)
200{
201 if (msg == NULL) {
202 return PLDM_ERROR_INVALID_DATA;
203 }
204
205 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
206 field == NULL) {
207 return PLDM_ERROR_INVALID_DATA;
208 }
209
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930210 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930211 header.msg_type = PLDM_REQUEST;
212 header.instance = instance_id;
213 header.pldm_type = PLDM_PLATFORM;
214 header.command = PLDM_SET_STATE_EFFECTER_STATES;
215
216 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
217 if (rc != PLDM_SUCCESS) {
218 return rc;
219 }
220
221 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930222 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930223 effecter_id = htole16(effecter_id);
224 request->effecter_id = effecter_id;
225 request->comp_effecter_count = comp_effecter_count;
226 memcpy(request->field, field,
227 (sizeof(set_effecter_state_field) * comp_effecter_count));
228
229 return PLDM_SUCCESS;
230}
231
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930232LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930233int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
234 size_t payload_length,
235 uint8_t *completion_code)
236{
237 if (msg == NULL || completion_code == NULL) {
238 return PLDM_ERROR_INVALID_DATA;
239 }
240
241 *completion_code = msg->payload[0];
242 if (PLDM_SUCCESS != *completion_code) {
243 return PLDM_SUCCESS;
244 }
245
246 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
247 return PLDM_ERROR_INVALID_LENGTH;
248 }
249
250 return PLDM_SUCCESS;
251}
252
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930253#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930254LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930255int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
256 size_t payload_length,
257 uint16_t *effecter_id,
258 uint8_t *comp_effecter_count,
259 set_effecter_state_field *field)
260{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930261 struct pldm_msgbuf _buf;
262 struct pldm_msgbuf *buf = &_buf;
263 int rc;
264 int i;
265
Andrew Jeffery9c766792022-08-10 23:12:49 +0930266 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
267 field == NULL) {
268 return PLDM_ERROR_INVALID_DATA;
269 }
270
271 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
272 return PLDM_ERROR_INVALID_LENGTH;
273 }
274
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930275 rc = pldm_msgbuf_init_cc(buf, PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
276 msg->payload, payload_length);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930277 if (rc) {
278 return rc;
279 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930280
Andrew Jeffery66c77232024-04-24 11:42:02 +0930281 pldm_msgbuf_extract_p(buf, effecter_id);
282 pldm_msgbuf_extract_p(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930283
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930284 if (*comp_effecter_count > 8) {
285 return PLDM_ERROR_INVALID_DATA;
286 }
287
288 for (i = 0; i < *comp_effecter_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930289 pldm_msgbuf_extract(buf, field[i].set_request);
290 pldm_msgbuf_extract(buf, field[i].effecter_state);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930291 }
292
293 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930294}
295
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930296LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930297int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
298 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
299 uint8_t *transfer_op_flag, uint16_t *request_cnt,
300 uint16_t *record_chg_num)
301{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930302 struct pldm_msgbuf _buf;
303 struct pldm_msgbuf *buf = &_buf;
304 int rc;
305
Andrew Jeffery9c766792022-08-10 23:12:49 +0930306 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
307 transfer_op_flag == NULL || request_cnt == NULL ||
308 record_chg_num == NULL) {
309 return PLDM_ERROR_INVALID_DATA;
310 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930311
Andrew Jeffery9c766792022-08-10 23:12:49 +0930312 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
313 return PLDM_ERROR_INVALID_LENGTH;
314 }
315
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930316 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
317 payload_length);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930318 if (rc) {
319 return rc;
320 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930321
Andrew Jeffery66c77232024-04-24 11:42:02 +0930322 pldm_msgbuf_extract_p(buf, record_hndl);
323 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
324 pldm_msgbuf_extract_p(buf, transfer_op_flag);
325 pldm_msgbuf_extract_p(buf, request_cnt);
326 pldm_msgbuf_extract_p(buf, record_chg_num);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930327
328 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930329}
330
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930331LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930332int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
333 uint32_t next_record_hndl,
334 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
335 uint16_t resp_cnt, const uint8_t *record_data,
336 uint8_t transfer_crc, struct pldm_msg *msg)
337{
338 if (msg == NULL) {
339 return PLDM_ERROR_INVALID_DATA;
340 }
341
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930342 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930343 header.msg_type = PLDM_RESPONSE;
344 header.instance = instance_id;
345 header.pldm_type = PLDM_PLATFORM;
346 header.command = PLDM_GET_PDR;
347
348 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
349 if (rc != PLDM_SUCCESS) {
350 return rc;
351 }
352
353 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930354 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930355 response->completion_code = completion_code;
356
357 if (response->completion_code == PLDM_SUCCESS) {
358 response->next_record_handle = htole32(next_record_hndl);
359 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930360 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930361 response->transfer_flag = transfer_flag;
362 response->response_count = htole16(resp_cnt);
363 if (record_data != NULL && resp_cnt > 0) {
364 memcpy(response->record_data, record_data, resp_cnt);
365 }
366 if (transfer_flag == PLDM_END) {
367 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930368 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
369 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930370 *dst = transfer_crc;
371 }
372 }
373
374 return PLDM_SUCCESS;
375}
376
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930377LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930378int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930379 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
380 const uint8_t *update_time, const uint8_t *oem_update_time,
381 uint32_t record_count, uint32_t repository_size,
382 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
383 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930384{
385 if (msg == NULL) {
386 return PLDM_ERROR_INVALID_DATA;
387 }
388
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930389 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930390 header.msg_type = PLDM_RESPONSE;
391 header.instance = instance_id;
392 header.pldm_type = PLDM_PLATFORM;
393 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
394
395 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
396 if (rc != PLDM_SUCCESS) {
397 return rc;
398 }
399
400 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930401 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930402 response->completion_code = completion_code;
403
404 if (response->completion_code == PLDM_SUCCESS) {
405 response->repository_state = repository_state;
406 if (update_time != NULL) {
407 memcpy(response->update_time, update_time,
408 PLDM_TIMESTAMP104_SIZE);
409 }
410 if (oem_update_time != NULL) {
411 memcpy(response->oem_update_time, oem_update_time,
412 PLDM_TIMESTAMP104_SIZE);
413 }
414 response->record_count = htole32(record_count);
415 response->repository_size = htole32(repository_size);
416 response->largest_record_size = htole32(largest_record_size);
417 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930418 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930419 }
420
421 return PLDM_SUCCESS;
422}
423
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930424LIBPLDM_ABI_STABLE
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800425int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930426 const struct pldm_msg *msg, size_t payload_length,
427 uint8_t *completion_code, uint8_t *repository_state,
428 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
429 uint32_t *repository_size, uint32_t *largest_record_size,
430 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800431{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930432 struct pldm_msgbuf _buf;
433 struct pldm_msgbuf *buf = &_buf;
434 int rc;
435
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800436 if (msg == NULL || completion_code == NULL ||
437 repository_state == NULL || update_time == NULL ||
438 oem_update_time == NULL || record_count == NULL ||
439 repository_size == NULL || largest_record_size == NULL ||
440 data_transfer_handle_timeout == NULL) {
441 return PLDM_ERROR_INVALID_DATA;
442 }
443
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930444 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
445 msg->payload, payload_length);
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930446 if (rc) {
447 return rc;
448 }
449
Andrew Jeffery66c77232024-04-24 11:42:02 +0930450 pldm_msgbuf_extract_p(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800451 if (PLDM_SUCCESS != *completion_code) {
452 return PLDM_SUCCESS;
453 }
454
Andrew Jeffery66c77232024-04-24 11:42:02 +0930455 pldm_msgbuf_extract_p(buf, repository_state);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800456 if (*repository_state > PLDM_FAILED) {
457 return PLDM_ERROR_INVALID_DATA;
458 }
459
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930460 pldm_msgbuf_extract_array(buf, update_time, PLDM_TIMESTAMP104_SIZE);
461 pldm_msgbuf_extract_array(buf, oem_update_time, PLDM_TIMESTAMP104_SIZE);
Andrew Jeffery66c77232024-04-24 11:42:02 +0930462 pldm_msgbuf_extract_p(buf, record_count);
463 pldm_msgbuf_extract_p(buf, repository_size);
464 pldm_msgbuf_extract_p(buf, largest_record_size);
465 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800466
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930467 return pldm_msgbuf_destroy(buf);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800468}
469
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930470LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930471int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
472 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
473 uint16_t request_cnt, uint16_t record_chg_num,
474 struct pldm_msg *msg, size_t payload_length)
475{
476 if (msg == NULL) {
477 return PLDM_ERROR_INVALID_DATA;
478 }
479
480 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
481 return PLDM_ERROR_INVALID_LENGTH;
482 }
483
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930484 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930485 header.msg_type = PLDM_REQUEST;
486 header.instance = instance_id;
487 header.pldm_type = PLDM_PLATFORM;
488 header.command = PLDM_GET_PDR;
489
490 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
491 if (rc != PLDM_SUCCESS) {
492 return rc;
493 }
494
495 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930496 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930497 request->record_handle = htole32(record_hndl);
498 request->data_transfer_handle = htole32(data_transfer_hndl);
499 request->transfer_op_flag = transfer_op_flag;
500 request->request_count = htole16(request_cnt);
501 request->record_change_number = htole16(record_chg_num);
502
503 return PLDM_SUCCESS;
504}
505
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930506LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930507int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
508 uint8_t *completion_code, uint32_t *next_record_hndl,
509 uint32_t *next_data_transfer_hndl,
510 uint8_t *transfer_flag, uint16_t *resp_cnt,
511 uint8_t *record_data, size_t record_data_length,
512 uint8_t *transfer_crc)
513{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930514 struct pldm_msgbuf _buf;
515 struct pldm_msgbuf *buf = &_buf;
516 int rc;
517
Andrew Jeffery9c766792022-08-10 23:12:49 +0930518 if (msg == NULL || completion_code == NULL ||
519 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
520 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
521 return PLDM_ERROR_INVALID_DATA;
522 }
523
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930524 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
525 payload_length);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930526 if (rc) {
527 return rc;
528 }
529
Andrew Jeffery66c77232024-04-24 11:42:02 +0930530 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930531 if (PLDM_SUCCESS != *completion_code) {
532 return PLDM_SUCCESS;
533 }
534
Andrew Jeffery66c77232024-04-24 11:42:02 +0930535 pldm_msgbuf_extract_p(buf, next_record_hndl);
536 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
537 pldm_msgbuf_extract_p(buf, transfer_flag);
538 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930539 if (rc) {
540 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930541 }
542
543 if (*resp_cnt > 0 && record_data != NULL) {
544 if (record_data_length < *resp_cnt) {
545 return PLDM_ERROR_INVALID_LENGTH;
546 }
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930547 pldm_msgbuf_extract_array(buf, record_data, *resp_cnt);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930548 }
549
550 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930551 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930552 }
553
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930554 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930555}
556
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930557LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930558int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
559 size_t payload_length,
560 uint16_t *effecter_id,
561 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930562 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930563{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930564 struct pldm_msgbuf _buf;
565 struct pldm_msgbuf *buf = &_buf;
566 int rc;
567
Andrew Jeffery9c766792022-08-10 23:12:49 +0930568 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
569 effecter_value == NULL) {
570 return PLDM_ERROR_INVALID_DATA;
571 }
572
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930573 rc = pldm_msgbuf_init_cc(buf,
574 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
575 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930576 if (rc) {
577 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930578 }
579
Andrew Jeffery66c77232024-04-24 11:42:02 +0930580 pldm_msgbuf_extract_p(buf, effecter_id);
581 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930582 if (rc) {
583 return PLDM_ERROR_INVALID_DATA;
584 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930585
586 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
587 return PLDM_ERROR_INVALID_DATA;
588 }
589
Andrew Jeffery3884c442023-04-12 11:13:24 +0930590 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
591 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930592
Andrew Jeffery3884c442023-04-12 11:13:24 +0930593 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930594}
595
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930596LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930597int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
598 uint8_t completion_code,
599 struct pldm_msg *msg,
600 size_t payload_length)
601{
602 if (msg == NULL) {
603 return PLDM_ERROR_INVALID_DATA;
604 }
605
606 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
607 return PLDM_ERROR_INVALID_LENGTH;
608 }
609
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930610 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930611 header.msg_type = PLDM_RESPONSE;
612 header.instance = instance_id;
613 header.pldm_type = PLDM_PLATFORM;
614 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
615
616 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
617 if (rc != PLDM_SUCCESS) {
618 return rc;
619 }
620
621 msg->payload[0] = completion_code;
622
623 return rc;
624}
625
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930626LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930627int encode_set_numeric_effecter_value_req(uint8_t instance_id,
628 uint16_t effecter_id,
629 uint8_t effecter_data_size,
630 const uint8_t *effecter_value,
631 struct pldm_msg *msg,
632 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930633{
634 if (msg == NULL || effecter_value == NULL) {
635 return PLDM_ERROR_INVALID_DATA;
636 }
637
638 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
639 return PLDM_ERROR_INVALID_DATA;
640 }
641
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930642 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930643 header.msg_type = PLDM_REQUEST;
644 header.instance = instance_id;
645 header.pldm_type = PLDM_PLATFORM;
646 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
647
648 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
649 if (rc != PLDM_SUCCESS) {
650 return rc;
651 }
652
653 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930654 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930655 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
656 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
657 if (payload_length !=
658 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
659 return PLDM_ERROR_INVALID_LENGTH;
660 }
661 request->effecter_value[0] = *effecter_value;
662 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
663 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
664 if (payload_length !=
665 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
666 return PLDM_ERROR_INVALID_LENGTH;
667 }
668
669 uint16_t val = *(uint16_t *)(effecter_value);
670 val = htole16(val);
671 memcpy(request->effecter_value, &val, sizeof(uint16_t));
672
673 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
674 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
675 if (payload_length !=
676 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
677 return PLDM_ERROR_INVALID_LENGTH;
678 }
679
680 uint32_t val = *(uint32_t *)(effecter_value);
681 val = htole32(val);
682 memcpy(request->effecter_value, &val, sizeof(uint32_t));
683 }
684
685 request->effecter_id = htole16(effecter_id);
686 request->effecter_data_size = effecter_data_size;
687
688 return PLDM_SUCCESS;
689}
690
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930691LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930692int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
693 size_t payload_length,
694 uint8_t *completion_code)
695{
696 if (msg == NULL || completion_code == NULL) {
697 return PLDM_ERROR_INVALID_DATA;
698 }
699
700 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
701 return PLDM_ERROR_INVALID_LENGTH;
702 }
703
704 *completion_code = msg->payload[0];
705
706 return PLDM_SUCCESS;
707}
708
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930709LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930710int encode_get_state_sensor_readings_resp(uint8_t instance_id,
711 uint8_t completion_code,
712 uint8_t comp_sensor_count,
713 get_sensor_state_field *field,
714 struct pldm_msg *msg)
715{
716 if (msg == NULL) {
717 return PLDM_ERROR_INVALID_DATA;
718 }
719
720 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
721 return PLDM_ERROR_INVALID_DATA;
722 }
723
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930724 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930725 header.msg_type = PLDM_RESPONSE;
726 header.instance = instance_id;
727 header.pldm_type = PLDM_PLATFORM;
728 header.command = PLDM_GET_STATE_SENSOR_READINGS;
729
730 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
731 if (rc != PLDM_SUCCESS) {
732 return rc;
733 }
734
735 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930736 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930737
738 response->completion_code = completion_code;
739 response->comp_sensor_count = comp_sensor_count;
740 memcpy(response->field, field,
741 (sizeof(get_sensor_state_field) * comp_sensor_count));
742
743 return PLDM_SUCCESS;
744}
745
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930746LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930747int encode_get_state_sensor_readings_req(uint8_t instance_id,
748 uint16_t sensor_id,
749 bitfield8_t sensor_rearm,
750 uint8_t reserved, struct pldm_msg *msg)
751{
752 if (msg == NULL) {
753 return PLDM_ERROR_INVALID_DATA;
754 }
755
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930756 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930757 header.msg_type = PLDM_REQUEST;
758 header.instance = instance_id;
759 header.pldm_type = PLDM_PLATFORM;
760 header.command = PLDM_GET_STATE_SENSOR_READINGS;
761
762 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
763 if (rc != PLDM_SUCCESS) {
764 return rc;
765 }
766
767 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930768 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930769
770 request->sensor_id = htole16(sensor_id);
771 request->reserved = reserved;
772 request->sensor_rearm = sensor_rearm;
773
774 return PLDM_SUCCESS;
775}
776
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930777LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930778int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
779 size_t payload_length,
780 uint8_t *completion_code,
781 uint8_t *comp_sensor_count,
782 get_sensor_state_field *field)
783{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930784 struct pldm_msgbuf _buf;
785 struct pldm_msgbuf *buf = &_buf;
786 uint8_t i;
787 int rc;
788
Andrew Jeffery9c766792022-08-10 23:12:49 +0930789 if (msg == NULL || completion_code == NULL ||
790 comp_sensor_count == NULL || field == NULL) {
791 return PLDM_ERROR_INVALID_DATA;
792 }
793
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930794 rc = pldm_msgbuf_init_cc(buf,
795 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
796 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930797 if (rc) {
798 return rc;
799 }
800
Andrew Jeffery66c77232024-04-24 11:42:02 +0930801 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930802 if (rc) {
803 return rc;
804 }
805
Andrew Jeffery9c766792022-08-10 23:12:49 +0930806 if (PLDM_SUCCESS != *completion_code) {
807 return PLDM_SUCCESS;
808 }
809
Andrew Jeffery66c77232024-04-24 11:42:02 +0930810 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930811 if (rc) {
812 return rc;
813 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930814
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930815 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930816 return PLDM_ERROR_INVALID_DATA;
817 }
818
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930819 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930820 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
821 pldm_msgbuf_extract(buf, field[i].present_state);
822 pldm_msgbuf_extract(buf, field[i].previous_state);
823 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930824 }
825
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930826 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930827}
828
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930829LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930830int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
831 size_t payload_length,
832 uint16_t *sensor_id,
833 bitfield8_t *sensor_rearm,
834 uint8_t *reserved)
835{
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930836 struct pldm_msgbuf _buf;
837 struct pldm_msgbuf *buf = &_buf;
838 int rc;
839
Andrew Jeffery9c766792022-08-10 23:12:49 +0930840 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
841 return PLDM_ERROR_INVALID_DATA;
842 }
843
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930844 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
845 msg->payload, payload_length);
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930846 if (rc) {
847 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930848 }
849
Andrew Jeffery66c77232024-04-24 11:42:02 +0930850 pldm_msgbuf_extract_p(buf, sensor_id);
851 pldm_msgbuf_extract(buf, sensor_rearm->byte);
852 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930853
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930854 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930855}
856
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930857LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930858int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930859 struct pldm_sensor_event_data *const event_data,
860 const size_t event_data_size, const uint16_t sensor_id,
861 const enum sensor_event_class_states sensor_event_class,
862 const uint8_t sensor_offset, const uint8_t event_state,
863 const uint8_t previous_event_state,
864 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930865{
866 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930867 (sizeof(*event_data) - sizeof(event_data->event_class) +
868 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930869
870 if (!event_data) {
871 return PLDM_SUCCESS;
872 }
873
874 if (event_data_size < *actual_event_data_size) {
875 *actual_event_data_size = 0;
876 return PLDM_ERROR_INVALID_LENGTH;
877 }
878
879 event_data->sensor_id = htole16(sensor_id);
880 event_data->sensor_event_class_type = sensor_event_class;
881
882 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930883 (struct pldm_sensor_event_state_sensor_state *)
884 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930885
886 state_data->sensor_offset = sensor_offset;
887 state_data->event_state = event_state;
888 state_data->previous_event_state = previous_event_state;
889
890 return PLDM_SUCCESS;
891}
892
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930893LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930894int decode_platform_event_message_req(const struct pldm_msg *msg,
895 size_t payload_length,
896 uint8_t *format_version, uint8_t *tid,
897 uint8_t *event_class,
898 size_t *event_data_offset)
899{
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930900 struct pldm_msgbuf _buf;
901 struct pldm_msgbuf *buf = &_buf;
902 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930903
904 if (msg == NULL || format_version == NULL || tid == NULL ||
905 event_class == NULL || event_data_offset == NULL) {
906 return PLDM_ERROR_INVALID_DATA;
907 }
908
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930909 rc = pldm_msgbuf_init_cc(buf, PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
910 msg->payload, payload_length);
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930911 if (rc) {
912 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930913 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930914
Andrew Jeffery66c77232024-04-24 11:42:02 +0930915 pldm_msgbuf_extract_p(buf, format_version);
916 pldm_msgbuf_extract_p(buf, tid);
917 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930918 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930919 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930920
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930921 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930922}
923
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930924LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700925int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930926 const struct pldm_msg *msg, size_t payload_length,
927 uint8_t *format_version, uint8_t *transfer_operation_flag,
928 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700929{
930 struct pldm_msgbuf _buf;
931 struct pldm_msgbuf *buf = &_buf;
932 int rc;
933
934 if (msg == NULL) {
935 return PLDM_ERROR_INVALID_DATA;
936 }
937
Andrew Jefferyc8df31c2024-05-21 16:47:43 +0930938 rc = pldm_msgbuf_init_cc(buf,
939 PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
940 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700941 if (rc) {
942 return rc;
943 }
944
Andrew Jeffery66c77232024-04-24 11:42:02 +0930945 pldm_msgbuf_extract_p(buf, format_version);
946 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700947 if (rc) {
948 return rc;
949 }
950 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
951 return PLDM_ERROR_INVALID_DATA;
952 }
953
Andrew Jeffery66c77232024-04-24 11:42:02 +0930954 pldm_msgbuf_extract_p(buf, data_transfer_handle);
955 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700956 if (rc) {
957 return rc;
958 }
959
960 if (!(((*transfer_operation_flag == PLDM_GET_NEXTPART) &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600961 (*event_id_to_acknowledge == 0xffff)) ||
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700962 ((*transfer_operation_flag == PLDM_GET_FIRSTPART) &&
963 (*event_id_to_acknowledge == 0x000)) ||
964 (*transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY))) {
965 return PLDM_ERROR_INVALID_DATA;
966 }
967
968 return pldm_msgbuf_destroy(buf);
969}
970
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930971LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930972int encode_platform_event_message_resp(uint8_t instance_id,
973 uint8_t completion_code,
974 uint8_t platform_event_status,
975 struct pldm_msg *msg)
976{
977 if (msg == NULL) {
978 return PLDM_ERROR_INVALID_DATA;
979 }
980
981 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
982 return PLDM_ERROR_INVALID_DATA;
983 }
984
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930985 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930986 header.msg_type = PLDM_RESPONSE;
987 header.instance = instance_id;
988 header.pldm_type = PLDM_PLATFORM;
989 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
990
991 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
992 if (rc != PLDM_SUCCESS) {
993 return rc;
994 }
995
996 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930997 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930998 response->completion_code = completion_code;
999 response->platform_event_status = platform_event_status;
1000
1001 return PLDM_SUCCESS;
1002}
1003
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301004LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001005int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301006 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1007 uint16_t event_id, uint32_t next_data_transfer_handle,
1008 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1009 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1010 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001011{
1012 struct pldm_msgbuf _buf;
1013 struct pldm_msgbuf *buf = &_buf;
1014 int rc;
1015
1016 if (!msg) {
1017 return PLDM_ERROR_INVALID_DATA;
1018 }
1019
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301020 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001021 header.msg_type = PLDM_RESPONSE;
1022 header.instance = instance_id;
1023 header.pldm_type = PLDM_PLATFORM;
1024 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1025
1026 rc = pack_pldm_header(&header, &(msg->hdr));
1027 if (rc != PLDM_SUCCESS) {
1028 return rc;
1029 }
1030
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301031 rc = pldm_msgbuf_init_cc(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301032 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1033 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001034 if (rc) {
1035 return rc;
1036 }
1037
1038 pldm_msgbuf_insert(buf, completion_code);
1039 pldm_msgbuf_insert(buf, tid);
1040 pldm_msgbuf_insert(buf, event_id);
1041
1042 if (event_id == 0xffff || event_id == 0x0000) {
1043 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1044 payload_length) {
1045 return PLDM_ERROR_INVALID_LENGTH;
1046 }
1047 return pldm_msgbuf_destroy(buf);
1048 }
1049
1050 if ((event_data == NULL) && (event_data_size > 0)) {
1051 return PLDM_ERROR_INVALID_DATA;
1052 }
1053
1054 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1055 pldm_msgbuf_insert(buf, transfer_flag);
1056 pldm_msgbuf_insert(buf, event_class);
1057 pldm_msgbuf_insert(buf, event_data_size);
1058
1059 if ((event_data_size > 0) && event_data) {
1060 pldm_msgbuf_insert_array(buf, event_data, event_data_size);
1061 }
1062
1063 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1064 pldm_msgbuf_insert(buf, checksum);
1065 }
1066
1067 return pldm_msgbuf_destroy(buf);
1068}
1069
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301070LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301071int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301072 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1073 uint8_t event_class, const uint8_t *event_data,
1074 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301075
1076{
1077 if (format_version != 1) {
1078 return PLDM_ERROR_INVALID_DATA;
1079 }
1080
1081 if (msg == NULL || event_data == NULL) {
1082 return PLDM_ERROR_INVALID_DATA;
1083 }
1084
1085 if (event_data_length == 0) {
1086 return PLDM_ERROR_INVALID_DATA;
1087 }
1088
1089 if (payload_length !=
1090 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1091 return PLDM_ERROR_INVALID_LENGTH;
1092 }
1093
1094 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001095 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301096 return PLDM_ERROR_INVALID_DATA;
1097 }
1098
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301099 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301100 header.msg_type = PLDM_REQUEST;
1101 header.instance = instance_id;
1102 header.pldm_type = PLDM_PLATFORM;
1103 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1104
1105 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1106 if (rc != PLDM_SUCCESS) {
1107 return rc;
1108 }
1109
1110 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301111 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301112 request->format_version = format_version;
1113 request->tid = tid;
1114 request->event_class = event_class;
1115 memcpy(request->event_data, event_data, event_data_length);
1116
1117 return PLDM_SUCCESS;
1118}
1119
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301120LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301121int decode_platform_event_message_resp(const struct pldm_msg *msg,
1122 size_t payload_length,
1123 uint8_t *completion_code,
1124 uint8_t *platform_event_status)
1125{
Andrew Jefferye5011772023-04-13 12:06:22 +09301126 struct pldm_msgbuf _buf;
1127 struct pldm_msgbuf *buf = &_buf;
1128 int rc;
1129
Andrew Jeffery9c766792022-08-10 23:12:49 +09301130 if (msg == NULL || completion_code == NULL ||
1131 platform_event_status == NULL) {
1132 return PLDM_ERROR_INVALID_DATA;
1133 }
1134
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301135 rc = pldm_msgbuf_init_cc(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1136 msg->payload, payload_length);
Andrew Jefferye5011772023-04-13 12:06:22 +09301137 if (rc) {
1138 return rc;
1139 }
1140
Andrew Jeffery66c77232024-04-24 11:42:02 +09301141 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301142 if (rc) {
1143 return rc;
1144 }
1145
Andrew Jeffery9c766792022-08-10 23:12:49 +09301146 if (PLDM_SUCCESS != *completion_code) {
1147 return PLDM_SUCCESS;
1148 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301149
Andrew Jeffery66c77232024-04-24 11:42:02 +09301150 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301151 if (rc) {
1152 return rc;
1153 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301154
1155 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1156 return PLDM_ERROR_INVALID_DATA;
1157 }
1158
Andrew Jefferye5011772023-04-13 12:06:22 +09301159 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301160}
1161
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301162LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301163int encode_event_message_buffer_size_req(uint8_t instance_id,
1164 uint16_t event_receiver_max_buffer_size,
1165 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001166{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301167 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001168 header.msg_type = PLDM_REQUEST;
1169 header.instance = instance_id;
1170 header.pldm_type = PLDM_PLATFORM;
1171 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1172
1173 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1174 if (rc != PLDM_SUCCESS) {
1175 return rc;
1176 }
1177
1178 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301179 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001180 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301181 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001182
1183 return PLDM_SUCCESS;
1184}
1185
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301186LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001187int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1188 size_t payload_length,
1189 uint8_t *completion_code,
1190 uint16_t *terminus_max_buffer_size)
1191{
Andrew Jeffery11126902023-04-13 12:12:10 +09301192 struct pldm_msgbuf _buf;
1193 struct pldm_msgbuf *buf = &_buf;
1194 int rc;
1195
Dung Caod6ae8982022-11-02 10:00:10 +07001196 if (msg == NULL || completion_code == NULL ||
1197 terminus_max_buffer_size == NULL) {
1198 return PLDM_ERROR_INVALID_DATA;
1199 }
1200
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301201 rc = pldm_msgbuf_init_cc(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1202 msg->payload, payload_length);
Andrew Jeffery11126902023-04-13 12:12:10 +09301203 if (rc) {
1204 return rc;
1205 }
1206
Andrew Jeffery66c77232024-04-24 11:42:02 +09301207 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301208 if (rc) {
1209 return rc;
1210 }
1211
Dung Caod6ae8982022-11-02 10:00:10 +07001212 if (PLDM_SUCCESS != *completion_code) {
1213 return PLDM_SUCCESS;
1214 }
Dung Caod6ae8982022-11-02 10:00:10 +07001215
Andrew Jeffery66c77232024-04-24 11:42:02 +09301216 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001217
Andrew Jeffery11126902023-04-13 12:12:10 +09301218 return pldm_msgbuf_destroy_consumed(buf);
Dung Caod6ae8982022-11-02 10:00:10 +07001219}
1220
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301221LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001222int encode_event_message_supported_req(uint8_t instance_id,
1223 uint8_t format_version,
1224 struct pldm_msg *msg)
1225{
1226 if (format_version != 1) {
1227 return PLDM_ERROR_INVALID_DATA;
1228 }
1229
1230 if (msg == NULL) {
1231 return PLDM_ERROR_INVALID_DATA;
1232 }
1233
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301234 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001235 header.msg_type = PLDM_REQUEST;
1236 header.instance = instance_id;
1237 header.pldm_type = PLDM_PLATFORM;
1238 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1239
1240 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1241 if (rc != PLDM_SUCCESS) {
1242 return rc;
1243 }
1244
1245 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301246 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001247 request->format_version = format_version;
1248
1249 return PLDM_SUCCESS;
1250}
1251
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301252LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301253int decode_event_message_supported_resp(const struct pldm_msg *msg,
1254 size_t payload_length,
1255 uint8_t *completion_code,
1256 uint8_t *synchrony_config,
1257 bitfield8_t *synchrony_config_support,
1258 uint8_t *number_event_class_returned,
1259 uint8_t *event_class,
1260 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001261{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301262 struct pldm_msgbuf _buf;
1263 struct pldm_msgbuf *buf = &_buf;
1264 int i;
1265 int rc;
1266
Dung Cao1bf8c872022-11-29 05:32:58 +07001267 if (msg == NULL || completion_code == NULL ||
1268 synchrony_config == NULL || synchrony_config_support == NULL ||
1269 number_event_class_returned == NULL || event_class == NULL) {
1270 return PLDM_ERROR_INVALID_DATA;
1271 }
1272
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301273 rc = pldm_msgbuf_init_cc(buf,
1274 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1275 msg->payload, payload_length);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301276 if (rc) {
1277 return rc;
1278 }
1279
Andrew Jeffery66c77232024-04-24 11:42:02 +09301280 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301281 if (rc) {
1282 return rc;
1283 }
1284
Dung Cao1bf8c872022-11-29 05:32:58 +07001285 if (PLDM_SUCCESS != *completion_code) {
1286 return PLDM_SUCCESS;
1287 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301288
Andrew Jeffery66c77232024-04-24 11:42:02 +09301289 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301290 if (rc) {
1291 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001292 }
1293
Dung Cao1bf8c872022-11-29 05:32:58 +07001294 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1295 return PLDM_ERROR_INVALID_DATA;
1296 }
1297
Andrew Jeffery66c77232024-04-24 11:42:02 +09301298 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001299
Andrew Jeffery66c77232024-04-24 11:42:02 +09301300 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301301 if (rc) {
1302 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001303 }
1304
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301305 if (*number_event_class_returned == 0) {
1306 return pldm_msgbuf_destroy(buf);
1307 }
1308
1309 if (event_class_count < *number_event_class_returned) {
1310 return PLDM_ERROR_INVALID_LENGTH;
1311 }
1312
1313 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301314 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301315 }
1316
1317 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao1bf8c872022-11-29 05:32:58 +07001318}
1319
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301320LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301321int decode_sensor_event_data(const uint8_t *event_data,
1322 size_t event_data_length, uint16_t *sensor_id,
1323 uint8_t *sensor_event_class_type,
1324 size_t *event_class_data_offset)
1325{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301326 struct pldm_msgbuf _buf;
1327 struct pldm_msgbuf *buf = &_buf;
1328 int rc;
1329
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301330 rc = pldm_msgbuf_init_cc(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1331 event_data, event_data_length);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301332 if (rc) {
1333 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301334 }
1335
1336 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301337 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301338
Andrew Jeffery66c77232024-04-24 11:42:02 +09301339 pldm_msgbuf_extract_p(buf, sensor_id);
1340 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301341 if (rc) {
1342 return rc;
1343 }
1344
1345 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301346 if (event_class_data_length !=
1347 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1348 return PLDM_ERROR_INVALID_LENGTH;
1349 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301350 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301351 if (event_class_data_length !=
1352 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1353 return PLDM_ERROR_INVALID_LENGTH;
1354 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301355 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301356 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301357 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301358 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301359 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301360 return PLDM_ERROR_INVALID_LENGTH;
1361 }
1362 } else {
1363 return PLDM_ERROR_INVALID_DATA;
1364 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301365
Andrew Jeffery9c766792022-08-10 23:12:49 +09301366 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301367 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301368
1369 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301370}
1371
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301372LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301373int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1374 uint8_t *present_op_state, uint8_t *previous_op_state)
1375{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301376 struct pldm_msgbuf _buf;
1377 struct pldm_msgbuf *buf = &_buf;
1378 int rc;
1379
1380 if (present_op_state == NULL || previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301381 return PLDM_ERROR_INVALID_DATA;
1382 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301383
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301384 rc = pldm_msgbuf_init_cc(buf,
1385 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH,
1386 sensor_data, sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301387 if (rc) {
1388 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301389 }
1390
Andrew Jeffery66c77232024-04-24 11:42:02 +09301391 pldm_msgbuf_extract_p(buf, present_op_state);
1392 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301393
1394 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301395}
1396
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301397LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301398int decode_state_sensor_data(const uint8_t *sensor_data,
1399 size_t sensor_data_length, uint8_t *sensor_offset,
1400 uint8_t *event_state,
1401 uint8_t *previous_event_state)
1402{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301403 struct pldm_msgbuf _buf;
1404 struct pldm_msgbuf *buf = &_buf;
1405 int rc;
1406
1407 if (sensor_offset == NULL || event_state == NULL ||
1408 previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301409 return PLDM_ERROR_INVALID_DATA;
1410 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301411
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301412 rc = pldm_msgbuf_init_cc(
1413 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1414 sensor_data, sensor_data_length);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301415 if (rc) {
1416 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301417 }
1418
Andrew Jeffery66c77232024-04-24 11:42:02 +09301419 pldm_msgbuf_extract_p(buf, sensor_offset);
1420 pldm_msgbuf_extract_p(buf, event_state);
1421 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301422
1423 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301424}
1425
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301426LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301427int decode_numeric_sensor_data(const uint8_t *sensor_data,
1428 size_t sensor_data_length, uint8_t *event_state,
1429 uint8_t *previous_event_state,
1430 uint8_t *sensor_data_size,
1431 uint32_t *present_reading)
1432{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301433 struct pldm_msgbuf _buf;
1434 struct pldm_msgbuf *buf = &_buf;
1435 int rc;
1436
1437 if (sensor_data_size == NULL || event_state == NULL ||
1438 previous_event_state == NULL || present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301439 return PLDM_ERROR_INVALID_DATA;
1440 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301441
1442 if (sensor_data_length >
1443 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301444 return PLDM_ERROR_INVALID_LENGTH;
1445 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301446
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301447 rc = pldm_msgbuf_init_cc(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301448 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1449 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301450 if (rc) {
1451 return rc;
1452 }
1453
Andrew Jeffery66c77232024-04-24 11:42:02 +09301454 pldm_msgbuf_extract_p(buf, event_state);
1455 pldm_msgbuf_extract_p(buf, previous_event_state);
1456 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301457 if (rc) {
1458 return rc;
1459 }
1460
1461 /*
1462 * The implementation below is bonkers, but it's because the function
1463 * prototype is bonkers. The `present_reading` argument should have been
1464 * a tagged union.
1465 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301466 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301467 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1468 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301469 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301470 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301471 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301472 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301473 }
1474 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1475 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301476 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301477 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301478 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301479 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301480 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301481 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301482 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301483 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301484 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301485 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301486 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301487 }
1488 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301489 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301490 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301491 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301492 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301493 break;
1494 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301495 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1496 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301497 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301498 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301499 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301500 break;
1501 }
1502 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1503 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301504 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301505 *present_reading = (uint32_t)val;
1506 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301507 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301508 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301509 default:
1510 return PLDM_ERROR_INVALID_DATA;
1511 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301512
1513 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301514}
1515
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301516LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301517int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301518 const void *pdr_data, size_t pdr_data_length,
1519 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301520{
1521 struct pldm_msgbuf _buf;
1522 struct pldm_msgbuf *buf = &_buf;
1523 int rc;
1524
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301525 rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1526 pdr_data, pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301527 if (rc) {
1528 return rc;
1529 }
1530
1531 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1532 if (rc) {
1533 return rc;
1534 }
1535
1536 rc = pldm_platform_pdr_hdr_validate(
Thu Nguyen51230a02023-11-10 16:22:25 +07001537 &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301538 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301539 if (rc) {
1540 return rc;
1541 }
1542
Andrew Jeffery66c77232024-04-24 11:42:02 +09301543 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1544 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1545 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1546 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1547 pldm_msgbuf_extract(buf, pdr_value->container_id);
1548 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1549 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1550 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1551 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1552 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1553 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1554 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1555 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1556 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1557 pldm_msgbuf_extract(buf, pdr_value->rel);
1558 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1559 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301560
Andrew Jeffery66c77232024-04-24 11:42:02 +09301561 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301562 if (rc) {
1563 return rc;
1564 }
1565 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1566 return PLDM_ERROR_INVALID_DATA;
1567 }
1568
Andrew Jeffery66c77232024-04-24 11:42:02 +09301569 pldm_msgbuf_extract(buf, pdr_value->resolution);
1570 pldm_msgbuf_extract(buf, pdr_value->offset);
1571 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1572 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1573 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301574 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1575 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301576 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301577 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301578 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1579 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1580 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301581 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1582 &pdr_value->max_readable);
1583 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1584 &pdr_value->min_readable);
1585
Andrew Jeffery66c77232024-04-24 11:42:02 +09301586 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301587 if (rc) {
1588 return rc;
1589 }
1590 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1591 return PLDM_ERROR_INVALID_DATA;
1592 }
1593
Andrew Jeffery66c77232024-04-24 11:42:02 +09301594 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301595 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301596 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301597 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301598 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301599 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301600 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301601 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301602 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301603 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301604 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301605 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301606 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301607 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301608 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301609 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301610 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301611 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301612 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301613
1614 return pldm_msgbuf_destroy(buf);
1615}
1616
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301617LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301618int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1619 uint16_t effecter_id,
1620 struct pldm_msg *msg)
1621{
1622 if (msg == NULL) {
1623 return PLDM_ERROR_INVALID_DATA;
1624 }
1625
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301626 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301627 header.msg_type = PLDM_REQUEST;
1628 header.instance = instance_id;
1629 header.pldm_type = PLDM_PLATFORM;
1630 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1631
1632 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1633 if (rc != PLDM_SUCCESS) {
1634 return rc;
1635 }
1636
1637 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301638 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301639 request->effecter_id = htole16(effecter_id);
1640
1641 return PLDM_SUCCESS;
1642}
1643
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301644LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301645int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301646 uint8_t instance_id, uint8_t completion_code,
1647 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1648 const uint8_t *pending_value, const uint8_t *present_value,
1649 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301650{
1651 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1652 return PLDM_ERROR_INVALID_DATA;
1653 }
1654
1655 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1656 return PLDM_ERROR_INVALID_DATA;
1657 }
1658
1659 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1660 return PLDM_ERROR_INVALID_DATA;
1661 }
1662
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301663 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301664 header.msg_type = PLDM_RESPONSE;
1665 header.instance = instance_id;
1666 header.pldm_type = PLDM_PLATFORM;
1667 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1668
1669 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1670 if (rc != PLDM_SUCCESS) {
1671 return rc;
1672 }
1673
1674 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301675 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301676
1677 response->completion_code = completion_code;
1678 response->effecter_data_size = effecter_data_size;
1679 response->effecter_oper_state = effecter_oper_state;
1680
1681 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1682 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1683 if (payload_length !=
1684 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1685 return PLDM_ERROR_INVALID_LENGTH;
1686 }
1687 response->pending_and_present_values[0] = *pending_value;
1688 response->pending_and_present_values[1] = *present_value;
1689
1690 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1691 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1692 if (payload_length !=
1693 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1694 return PLDM_ERROR_INVALID_LENGTH;
1695 }
1696 uint16_t val_pending = *(uint16_t *)pending_value;
1697 val_pending = htole16(val_pending);
1698 memcpy(response->pending_and_present_values, &val_pending,
1699 sizeof(uint16_t));
1700 uint16_t val_present = *(uint16_t *)present_value;
1701 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301702 memcpy((response->pending_and_present_values +
1703 sizeof(uint16_t)),
1704 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301705
1706 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1707 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1708 if (payload_length !=
1709 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1710 return PLDM_ERROR_INVALID_LENGTH;
1711 }
1712 uint32_t val_pending = *(uint32_t *)pending_value;
1713 val_pending = htole32(val_pending);
1714 memcpy(response->pending_and_present_values, &val_pending,
1715 sizeof(uint32_t));
1716 uint32_t val_present = *(uint32_t *)present_value;
1717 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301718 memcpy((response->pending_and_present_values +
1719 sizeof(uint32_t)),
1720 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301721 }
1722 return PLDM_SUCCESS;
1723}
1724
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301725LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301726int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1727 size_t payload_length,
1728 uint16_t *effecter_id)
1729{
Andrew Jefferydd265822023-04-13 22:42:44 +09301730 struct pldm_msgbuf _buf;
1731 struct pldm_msgbuf *buf = &_buf;
1732 int rc;
1733
Andrew Jeffery9c766792022-08-10 23:12:49 +09301734 if (msg == NULL || effecter_id == NULL) {
1735 return PLDM_ERROR_INVALID_DATA;
1736 }
1737
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301738 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
1739 msg->payload, payload_length);
Andrew Jefferydd265822023-04-13 22:42:44 +09301740 if (rc) {
1741 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301742 }
1743
Andrew Jeffery66c77232024-04-24 11:42:02 +09301744 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301745
Andrew Jefferydd265822023-04-13 22:42:44 +09301746 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301747}
1748
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301749LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301750int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
1751 size_t payload_length,
1752 uint8_t *completion_code,
1753 uint8_t *effecter_data_size,
1754 uint8_t *effecter_oper_state,
1755 uint8_t *pending_value,
1756 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301757{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301758 struct pldm_msgbuf _buf;
1759 struct pldm_msgbuf *buf = &_buf;
1760 int rc;
1761
Andrew Jeffery9c766792022-08-10 23:12:49 +09301762 if (msg == NULL || effecter_data_size == NULL ||
1763 effecter_oper_state == NULL || pending_value == NULL ||
1764 present_value == NULL) {
1765 return PLDM_ERROR_INVALID_DATA;
1766 }
1767
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301768 rc = pldm_msgbuf_init_cc(buf,
1769 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
1770 msg->payload, payload_length);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301771 if (rc) {
1772 return rc;
1773 }
1774
Andrew Jeffery66c77232024-04-24 11:42:02 +09301775 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301776 if (rc) {
1777 return rc;
1778 }
1779
Andrew Jeffery9c766792022-08-10 23:12:49 +09301780 if (PLDM_SUCCESS != *completion_code) {
1781 return PLDM_SUCCESS;
1782 }
1783
Andrew Jeffery66c77232024-04-24 11:42:02 +09301784 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301785 if (rc) {
1786 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301787 }
1788
Andrew Jeffery9c766792022-08-10 23:12:49 +09301789 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1790 return PLDM_ERROR_INVALID_DATA;
1791 }
1792
Andrew Jeffery66c77232024-04-24 11:42:02 +09301793 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301794 if (rc) {
1795 return rc;
1796 }
1797
Andrew Jeffery9c766792022-08-10 23:12:49 +09301798 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1799 return PLDM_ERROR_INVALID_DATA;
1800 }
1801
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301802 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1803 pending_value);
1804 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1805 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301806
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301807 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301808}
1809
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301810LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301811int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301812 uint8_t event_data_format, uint8_t number_of_change_records,
1813 const uint8_t *event_data_operations,
1814 const uint8_t *numbers_of_change_entries,
1815 const uint32_t *const *change_entries,
1816 struct pldm_pdr_repository_chg_event_data *event_data,
1817 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301818{
1819 if (event_data_operations == NULL ||
1820 numbers_of_change_entries == NULL || change_entries == NULL) {
1821 return PLDM_ERROR_INVALID_DATA;
1822 }
1823
1824 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301825 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301826
1827 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301828 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301829 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301830 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301831
1832 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301833 expected_size += sizeof(*change_entries[0]) *
1834 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301835 }
1836
1837 *actual_change_records_size = expected_size;
1838
1839 if (event_data == NULL) {
1840 return PLDM_SUCCESS;
1841 }
1842
1843 if (max_change_records_size < expected_size) {
1844 return PLDM_ERROR_INVALID_LENGTH;
1845 }
1846
1847 event_data->event_data_format = event_data_format;
1848 event_data->number_of_change_records = number_of_change_records;
1849
1850 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301851 (struct pldm_pdr_repository_change_record_data *)
1852 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301853
1854 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1855 record_data->event_data_operation = event_data_operations[i];
1856 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301857 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301858
1859 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1860 ++j) {
1861 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301862 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301863 }
1864
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301865 record_data =
1866 (struct pldm_pdr_repository_change_record_data
1867 *)(record_data->change_entry +
1868 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301869 }
1870
1871 return PLDM_SUCCESS;
1872}
1873
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301874LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301875int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1876 size_t event_data_size,
1877 uint8_t *event_data_format,
1878 uint8_t *number_of_change_records,
1879 size_t *change_record_data_offset)
1880{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301881 struct pldm_msgbuf _buf;
1882 struct pldm_msgbuf *buf = &_buf;
1883 int rc;
1884
1885 if (event_data_format == NULL || number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301886 change_record_data_offset == NULL) {
1887 return PLDM_ERROR_INVALID_DATA;
1888 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301889
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301890 rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
1891 event_data, event_data_size);
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301892 if (rc) {
1893 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301894 }
1895
Andrew Jeffery66c77232024-04-24 11:42:02 +09301896 pldm_msgbuf_extract_p(buf, event_data_format);
1897 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301898
Andrew Jeffery9c766792022-08-10 23:12:49 +09301899 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301900 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301901
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301902 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301903}
1904
Thu Nguyenf874b382024-07-24 11:22:34 +00001905LIBPLDM_ABI_STABLE
Thu Nguyen7739d122024-07-26 11:36:39 +00001906int decode_pldm_message_poll_event_data(
1907 const void *event_data, size_t event_data_length,
1908 struct pldm_message_poll_event *poll_event)
Dung Cao7c250342022-11-16 22:40:37 +07001909{
1910 struct pldm_msgbuf _buf;
1911 struct pldm_msgbuf *buf = &_buf;
1912 int rc;
1913
Thu Nguyen7739d122024-07-26 11:36:39 +00001914 if (!poll_event) {
1915 return -EINVAL;
Dung Cao7c250342022-11-16 22:40:37 +07001916 }
1917
Thu Nguyen7739d122024-07-26 11:36:39 +00001918 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
1919 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07001920 if (rc) {
1921 return rc;
1922 }
1923
Thu Nguyen7739d122024-07-26 11:36:39 +00001924 pldm_msgbuf_extract(buf, poll_event->format_version);
1925 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
Dung Cao7c250342022-11-16 22:40:37 +07001926 if (rc) {
1927 return rc;
1928 }
1929
Thu Nguyen7739d122024-07-26 11:36:39 +00001930 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
1931 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07001932 }
1933
Thu Nguyen7739d122024-07-26 11:36:39 +00001934 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07001935
1936 return pldm_msgbuf_destroy_consumed(buf);
1937}
1938
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301939LIBPLDM_ABI_TESTING
Thu Nguyen7739d122024-07-26 11:36:39 +00001940int encode_pldm_message_poll_event_data(
1941 const struct pldm_message_poll_event *poll_event, void *event_data,
1942 size_t event_data_length)
Dung Cao7c250342022-11-16 22:40:37 +07001943{
1944 struct pldm_msgbuf _buf;
1945 struct pldm_msgbuf *buf = &_buf;
1946 int rc;
1947
Thu Nguyen7739d122024-07-26 11:36:39 +00001948 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
1949 return -EPROTO;
Dung Cao7c250342022-11-16 22:40:37 +07001950 }
1951
Thu Nguyen7739d122024-07-26 11:36:39 +00001952 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
1953 event_data_length);
Dung Cao7c250342022-11-16 22:40:37 +07001954 if (rc) {
1955 return rc;
1956 }
Thu Nguyen7739d122024-07-26 11:36:39 +00001957 pldm_msgbuf_insert(buf, poll_event->format_version);
1958 pldm_msgbuf_insert(buf, poll_event->event_id);
1959 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
Dung Cao7c250342022-11-16 22:40:37 +07001960
Thu Nguyen7739d122024-07-26 11:36:39 +00001961 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao7c250342022-11-16 22:40:37 +07001962}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301963
1964LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301965int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301966 const uint8_t *change_record_data, size_t change_record_data_size,
1967 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1968 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301969{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301970 struct pldm_msgbuf _buf;
1971 struct pldm_msgbuf *buf = &_buf;
1972 int rc;
1973
1974 if (event_data_operation == NULL || number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301975 change_entry_data_offset == NULL) {
1976 return PLDM_ERROR_INVALID_DATA;
1977 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301978
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09301979 rc = pldm_msgbuf_init_cc(buf,
1980 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
1981 change_record_data, change_record_data_size);
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301982 if (rc) {
1983 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301984 }
1985
Andrew Jeffery66c77232024-04-24 11:42:02 +09301986 pldm_msgbuf_extract_p(buf, event_data_operation);
1987 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301988
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301989 *change_entry_data_offset = sizeof(*event_data_operation) +
1990 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301991
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301992 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301993}
1994
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301995LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301996int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1997 uint8_t rearm_event_state,
1998 struct pldm_msg *msg)
1999{
2000 if (msg == NULL) {
2001 return PLDM_ERROR_INVALID_DATA;
2002 }
2003
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302004 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302005 header.msg_type = PLDM_REQUEST;
2006 header.instance = instance_id;
2007 header.pldm_type = PLDM_PLATFORM;
2008 header.command = PLDM_GET_SENSOR_READING;
2009
2010 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2011 if (rc != PLDM_SUCCESS) {
2012 return rc;
2013 }
2014
2015 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302016 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302017
2018 request->sensor_id = htole16(sensor_id);
2019 request->rearm_event_state = rearm_event_state;
2020
2021 return PLDM_SUCCESS;
2022}
2023
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302024LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302025int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302026 const struct pldm_msg *msg, size_t payload_length,
2027 uint8_t *completion_code, uint8_t *sensor_data_size,
2028 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2029 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2030 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302031{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302032 struct pldm_msgbuf _buf;
2033 struct pldm_msgbuf *buf = &_buf;
2034 int rc;
2035
Andrew Jeffery9c766792022-08-10 23:12:49 +09302036 if (msg == NULL || completion_code == NULL ||
2037 sensor_data_size == NULL || sensor_operational_state == NULL ||
2038 sensor_event_message_enable == NULL || present_state == NULL ||
2039 previous_state == NULL || event_state == NULL ||
2040 present_reading == NULL) {
2041 return PLDM_ERROR_INVALID_DATA;
2042 }
2043
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09302044 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2045 msg->payload, payload_length);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302046 if (rc) {
2047 return rc;
2048 }
2049
Andrew Jeffery66c77232024-04-24 11:42:02 +09302050 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302051 if (rc) {
2052 return rc;
2053 }
2054
Andrew Jeffery9c766792022-08-10 23:12:49 +09302055 if (PLDM_SUCCESS != *completion_code) {
2056 return PLDM_SUCCESS;
2057 }
2058
Andrew Jeffery66c77232024-04-24 11:42:02 +09302059 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302060 if (rc) {
2061 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302062 }
2063
Andrew Jeffery840b1402023-04-13 23:54:44 +09302064 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302065 return PLDM_ERROR_INVALID_DATA;
2066 }
2067
Andrew Jeffery66c77232024-04-24 11:42:02 +09302068 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2069 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2070 pldm_msgbuf_extract_p(buf, present_state);
2071 pldm_msgbuf_extract_p(buf, previous_state);
2072 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302073
Andrew Jeffery840b1402023-04-13 23:54:44 +09302074 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2075 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302076
Andrew Jeffery840b1402023-04-13 23:54:44 +09302077 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302078}
2079
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302080LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302081int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2082 uint8_t sensor_data_size,
2083 uint8_t sensor_operational_state,
2084 uint8_t sensor_event_message_enable,
2085 uint8_t present_state,
2086 uint8_t previous_state, uint8_t event_state,
2087 const uint8_t *present_reading,
2088 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302089{
2090 if (msg == NULL || present_reading == NULL) {
2091 return PLDM_ERROR_INVALID_DATA;
2092 }
2093
2094 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2095 return PLDM_ERROR_INVALID_DATA;
2096 }
2097
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302098 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302099 header.msg_type = PLDM_RESPONSE;
2100 header.instance = instance_id;
2101 header.pldm_type = PLDM_PLATFORM;
2102 header.command = PLDM_GET_SENSOR_READING;
2103
2104 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2105 if (rc != PLDM_SUCCESS) {
2106 return rc;
2107 }
2108
2109 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302110 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302111
2112 response->completion_code = completion_code;
2113 response->sensor_data_size = sensor_data_size;
2114 response->sensor_operational_state = sensor_operational_state;
2115 response->sensor_event_message_enable = sensor_event_message_enable;
2116 response->present_state = present_state;
2117 response->previous_state = previous_state;
2118 response->event_state = event_state;
2119
2120 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2121 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2122 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2123 return PLDM_ERROR_INVALID_LENGTH;
2124 }
2125 response->present_reading[0] = *present_reading;
2126
2127 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2128 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2129 if (payload_length !=
2130 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2131 return PLDM_ERROR_INVALID_LENGTH;
2132 }
2133 uint16_t val = *(uint16_t *)present_reading;
2134 val = htole16(val);
2135 memcpy(response->present_reading, &val, 2);
2136
2137 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2138 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2139 if (payload_length !=
2140 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2141 return PLDM_ERROR_INVALID_LENGTH;
2142 }
2143 uint32_t val = *(uint32_t *)present_reading;
2144 val = htole32(val);
2145 memcpy(response->present_reading, &val, 4);
2146 }
2147
2148 return PLDM_SUCCESS;
2149}
2150
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302151LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302152int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2153 size_t payload_length, uint16_t *sensor_id,
2154 uint8_t *rearm_event_state)
2155{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302156 struct pldm_msgbuf _buf;
2157 struct pldm_msgbuf *buf = &_buf;
2158 int rc;
2159
Andrew Jeffery9c766792022-08-10 23:12:49 +09302160 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2161 return PLDM_ERROR_INVALID_DATA;
2162 }
2163
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09302164 rc = pldm_msgbuf_init_cc(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2165 msg->payload, payload_length);
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302166 if (rc) {
2167 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302168 }
2169
Andrew Jeffery66c77232024-04-24 11:42:02 +09302170 pldm_msgbuf_extract_p(buf, sensor_id);
2171 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302172
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302173 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302174}
2175
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302176LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302177int encode_set_event_receiver_req(uint8_t instance_id,
2178 uint8_t event_message_global_enable,
2179 uint8_t transport_protocol_type,
2180 uint8_t event_receiver_address_info,
2181 uint16_t heartbeat_timer,
2182 struct pldm_msg *msg)
2183{
2184 if (msg == NULL) {
2185 return PLDM_ERROR_INVALID_DATA;
2186 }
2187
2188 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2189 return PLDM_ERROR_INVALID_DATA;
2190 }
2191
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302192 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302193 header.msg_type = PLDM_REQUEST;
2194 header.instance = instance_id;
2195 header.pldm_type = PLDM_PLATFORM;
2196 header.command = PLDM_SET_EVENT_RECEIVER;
2197
2198 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2199 if (rc != PLDM_SUCCESS) {
2200 return rc;
2201 }
2202
2203 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302204 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302205 request->event_message_global_enable = event_message_global_enable;
2206
2207 request->transport_protocol_type = transport_protocol_type;
2208 request->event_receiver_address_info = event_receiver_address_info;
2209
2210 if (event_message_global_enable ==
2211 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2212 if (heartbeat_timer == 0) {
2213 return PLDM_ERROR_INVALID_DATA;
2214 }
2215 request->heartbeat_timer = htole16(heartbeat_timer);
2216 }
2217
2218 return PLDM_SUCCESS;
2219}
2220
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302221LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302222int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2223 size_t payload_length,
2224 uint8_t *completion_code)
2225{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302226 struct pldm_msgbuf _buf;
2227 struct pldm_msgbuf *buf = &_buf;
2228 int rc;
2229
Andrew Jeffery9c766792022-08-10 23:12:49 +09302230 if (msg == NULL || completion_code == NULL) {
2231 return PLDM_ERROR_INVALID_DATA;
2232 }
2233
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09302234 rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2235 msg->payload, payload_length);
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302236 if (rc) {
2237 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302238 }
2239
Andrew Jeffery66c77232024-04-24 11:42:02 +09302240 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302241
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302242 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302243}
2244
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302245LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302246int decode_set_event_receiver_req(const struct pldm_msg *msg,
2247 size_t payload_length,
2248 uint8_t *event_message_global_enable,
2249 uint8_t *transport_protocol_type,
2250 uint8_t *event_receiver_address_info,
2251 uint16_t *heartbeat_timer)
2252
2253{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302254 struct pldm_msgbuf _buf;
2255 struct pldm_msgbuf *buf = &_buf;
2256 int rc;
2257
Andrew Jeffery9c766792022-08-10 23:12:49 +09302258 if (msg == NULL || event_message_global_enable == NULL ||
2259 transport_protocol_type == NULL ||
2260 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2261 return PLDM_ERROR_INVALID_DATA;
2262 }
2263
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09302264 rc = pldm_msgbuf_init_cc(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2265 msg->payload, payload_length);
Andrew Jeffery9667f582023-04-14 00:39:21 +09302266 if (rc) {
2267 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302268 }
2269
Andrew Jeffery66c77232024-04-24 11:42:02 +09302270 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2271 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2272 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
2273 pldm_msgbuf_extract_p(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302274
Andrew Jeffery9667f582023-04-14 00:39:21 +09302275 rc = pldm_msgbuf_destroy(buf);
2276 if (rc) {
2277 return rc;
2278 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302279
Andrew Jeffery9c766792022-08-10 23:12:49 +09302280 if ((*event_message_global_enable ==
2281 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2282 (*heartbeat_timer == 0)) {
2283 return PLDM_ERROR_INVALID_DATA;
2284 }
2285
Andrew Jeffery9c766792022-08-10 23:12:49 +09302286 return PLDM_SUCCESS;
2287}
2288
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302289LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302290int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2291 struct pldm_msg *msg)
2292
2293{
2294 if (msg == NULL) {
2295 return PLDM_ERROR_INVALID_DATA;
2296 }
2297
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302298 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302299 header.instance = instance_id;
2300 header.msg_type = PLDM_RESPONSE;
2301 header.pldm_type = PLDM_PLATFORM;
2302 header.command = PLDM_SET_EVENT_RECEIVER;
2303
2304 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2305 if (rc != PLDM_SUCCESS) {
2306 return rc;
2307 }
2308
2309 msg->payload[0] = completion_code;
2310
2311 return PLDM_SUCCESS;
2312}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002313
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302314LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002315int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2316 uint8_t format_version,
2317 uint8_t transfer_operation_flag,
2318 uint32_t data_transfer_handle,
2319 uint16_t event_id_to_acknowledge,
2320 struct pldm_msg *msg,
2321 size_t payload_length)
2322{
2323 struct pldm_msgbuf _buf;
2324 struct pldm_msgbuf *buf = &_buf;
2325 int rc;
2326
2327 if (msg == NULL) {
2328 return PLDM_ERROR_INVALID_DATA;
2329 }
2330
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302331 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002332 header.msg_type = PLDM_REQUEST;
2333 header.instance = instance_id;
2334 header.pldm_type = PLDM_PLATFORM;
2335 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2336
2337 rc = pack_pldm_header(&header, &(msg->hdr));
2338 if (rc != PLDM_SUCCESS) {
2339 return rc;
2340 }
2341
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09302342 rc = pldm_msgbuf_init_cc(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302343 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2344 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002345 if (rc) {
2346 return rc;
2347 }
2348
2349 pldm_msgbuf_insert(buf, format_version);
2350 pldm_msgbuf_insert(buf, transfer_operation_flag);
2351 pldm_msgbuf_insert(buf, data_transfer_handle);
2352 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2353
2354 return pldm_msgbuf_destroy(buf);
2355}
2356
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302357LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002358int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302359 const struct pldm_msg *msg, size_t payload_length,
2360 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2361 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2362 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2363 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002364{
2365 struct pldm_msgbuf _buf;
2366 struct pldm_msgbuf *buf = &_buf;
2367 int rc;
2368
2369 if (msg == NULL || completion_code == NULL || tid == NULL ||
2370 event_id == NULL || next_data_transfer_handle == NULL ||
2371 transfer_flag == NULL || event_class == NULL ||
2372 event_data_size == NULL || event_data == NULL ||
2373 event_data_integrity_checksum == NULL) {
2374 return PLDM_ERROR_INVALID_DATA;
2375 }
2376
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09302377 rc = pldm_msgbuf_init_cc(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302378 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2379 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002380 if (rc) {
2381 return rc;
2382 }
2383
Andrew Jeffery66c77232024-04-24 11:42:02 +09302384 rc = pldm_msgbuf_extract_p(buf, completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002385 if (rc) {
2386 return rc;
2387 }
2388 if (PLDM_SUCCESS != *completion_code) {
2389 return *completion_code;
2390 }
2391
Andrew Jeffery66c77232024-04-24 11:42:02 +09302392 pldm_msgbuf_extract_p(buf, tid);
2393 rc = pldm_msgbuf_extract_p(buf, event_id);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002394 if (rc) {
2395 return rc;
2396 }
2397 if ((*event_id == 0) || (*event_id == 0xffff)) {
2398 return PLDM_SUCCESS;
2399 }
2400
Andrew Jeffery66c77232024-04-24 11:42:02 +09302401 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2402 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002403 if (rc) {
2404 return rc;
2405 }
2406
Andrew Jeffery66c77232024-04-24 11:42:02 +09302407 pldm_msgbuf_extract_p(buf, event_class);
2408 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002409 if (rc) {
2410 return rc;
2411 }
2412 if (*event_data_size > payload_length) {
2413 return PLDM_ERROR_INVALID_DATA;
2414 }
2415
2416 if (*event_data_size > 0) {
2417 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2418 }
2419
2420 if (*transfer_flag == PLDM_END ||
2421 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302422 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002423 }
2424
2425 return pldm_msgbuf_destroy_consumed(buf);
2426}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002427
2428LIBPLDM_ABI_TESTING
2429int decode_numeric_effecter_pdr_data(
2430 const void *pdr_data, size_t pdr_data_length,
2431 struct pldm_numeric_effecter_value_pdr *pdr_value)
2432{
2433 struct pldm_msgbuf _buf;
2434 struct pldm_msgbuf *buf = &_buf;
2435 struct pldm_value_pdr_hdr hdr;
2436 int rc;
2437
Andrew Jefferyc8df31c2024-05-21 16:47:43 +09302438 rc = pldm_msgbuf_init_cc(buf, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2439 pdr_data, pdr_data_length);
Thu Nguyend4878cd2023-11-09 10:18:33 +07002440 if (rc) {
2441 return rc;
2442 }
2443
2444 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &hdr);
2445 if (rc) {
2446 return rc;
2447 }
2448
2449 rc = pldm_platform_pdr_hdr_validate(
2450 &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2451 pdr_data_length);
2452 if (rc) {
2453 return rc;
2454 }
2455
2456 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2457
2458 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2459 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2460 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2461 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2462 pldm_msgbuf_extract(buf, pdr_value->container_id);
2463 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2464 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2465 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2466 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2467 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2468 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2469 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2470 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2471 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2472 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2473 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2474 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2475
2476 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2477 if (rc) {
2478 return rc;
2479 }
2480 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2481 return PLDM_ERROR_INVALID_DATA;
2482 }
2483
2484 pldm_msgbuf_extract(buf, pdr_value->resolution);
2485 pldm_msgbuf_extract(buf, pdr_value->offset);
2486 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2487 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2488 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2489 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2490 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2491 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2492 pdr_value->max_settable);
2493 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2494 pdr_value->min_settable);
2495
2496 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2497 if (rc) {
2498 return rc;
2499 }
2500 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2501 return PLDM_ERROR_INVALID_DATA;
2502 }
2503
2504 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2505 pldm_msgbuf_extract_range_field_format(
2506 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2507 pldm_msgbuf_extract_range_field_format(
2508 buf, pdr_value->range_field_format, pdr_value->normal_max);
2509 pldm_msgbuf_extract_range_field_format(
2510 buf, pdr_value->range_field_format, pdr_value->normal_min);
2511 pldm_msgbuf_extract_range_field_format(
2512 buf, pdr_value->range_field_format, pdr_value->rated_max);
2513 pldm_msgbuf_extract_range_field_format(
2514 buf, pdr_value->range_field_format, pdr_value->rated_min);
2515
2516 return pldm_msgbuf_destroy_consumed(buf);
2517}
Tal Yacobia6fa5552024-05-05 16:57:38 +03002518
Tal Yacobide67ab62024-05-30 22:36:50 +03002519LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002520int encode_get_state_effecter_states_req(uint8_t instance_id,
2521 uint16_t effecter_id,
2522 struct pldm_msg *msg,
2523 size_t payload_length)
2524{
2525 struct pldm_msgbuf _buf;
2526 struct pldm_msgbuf *buf = &_buf;
2527 int rc;
2528
2529 if (msg == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002530 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002531 }
2532
2533 struct pldm_header_info header = { 0 };
2534 header.msg_type = PLDM_REQUEST;
2535 header.instance = instance_id;
2536 header.pldm_type = PLDM_PLATFORM;
2537 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2538
Tal Yacobif490a382024-05-31 09:57:36 +03002539 rc = pack_pldm_header_errno(&header, &msg->hdr);
2540 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002541 return rc;
2542 }
2543
Tal Yacobif490a382024-05-31 09:57:36 +03002544 rc = pldm_msgbuf_init_errno(buf,
2545 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2546 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002547 if (rc) {
2548 return rc;
2549 }
2550
2551 pldm_msgbuf_insert(buf, effecter_id);
2552
2553 return pldm_msgbuf_destroy_consumed(buf);
2554}
2555
Tal Yacobide67ab62024-05-30 22:36:50 +03002556LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002557int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
2558 size_t payload_length,
2559 uint16_t *effecter_id)
2560{
2561 struct pldm_msgbuf _buf;
2562 struct pldm_msgbuf *buf = &_buf;
2563 int rc;
2564
2565 if (msg == NULL || effecter_id == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002566 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002567 }
2568
Tal Yacobif490a382024-05-31 09:57:36 +03002569 rc = pldm_msgbuf_init_errno(
2570 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2571 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002572 if (rc) {
2573 return rc;
2574 }
2575
2576 pldm_msgbuf_extract_p(buf, effecter_id);
2577
2578 return pldm_msgbuf_destroy_consumed(buf);
2579}
2580
Tal Yacobide67ab62024-05-30 22:36:50 +03002581LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002582int decode_get_state_effecter_states_resp(
2583 const struct pldm_msg *msg, size_t payload_length,
2584 struct pldm_get_state_effecter_states_resp *resp)
2585{
2586 struct pldm_msgbuf _buf;
2587 struct pldm_msgbuf *buf = &_buf;
2588 get_effecter_state_field *field;
2589 int rc;
2590 int i;
2591
2592 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002593 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002594 }
2595
Tal Yacobif490a382024-05-31 09:57:36 +03002596 rc = pldm_msgbuf_init_errno(
2597 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2598 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002599 if (rc) {
2600 return rc;
2601 }
2602
2603 rc = pldm_msgbuf_extract(buf, resp->completion_code);
2604 if (rc) {
2605 return rc;
2606 }
2607
2608 if (PLDM_SUCCESS != resp->completion_code) {
Tal Yacobif490a382024-05-31 09:57:36 +03002609 return 0;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002610 }
2611
2612 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
2613 if (rc) {
2614 return rc;
2615 }
2616
2617 uint8_t comp_effecter_count = resp->comp_effecter_count;
2618
2619 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2620 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002621 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002622 }
2623
2624 for (i = 0, field = resp->field; i < comp_effecter_count;
2625 i++, field++) {
2626 pldm_msgbuf_extract(buf, field->effecter_op_state);
2627 pldm_msgbuf_extract(buf, field->pending_state);
2628 pldm_msgbuf_extract(buf, field->present_state);
2629 }
2630
2631 return pldm_msgbuf_destroy_consumed(buf);
2632}
2633
Tal Yacobide67ab62024-05-30 22:36:50 +03002634LIBPLDM_ABI_STABLE
Tal Yacobia6fa5552024-05-05 16:57:38 +03002635int encode_get_state_effecter_states_resp(
2636 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
2637 struct pldm_msg *msg, size_t payload_length)
2638{
2639 struct pldm_msgbuf _buf;
2640 struct pldm_msgbuf *buf = &_buf;
2641 get_effecter_state_field *field;
2642 int rc;
2643 int i;
2644
2645 if (msg == NULL || resp == NULL) {
Tal Yacobif490a382024-05-31 09:57:36 +03002646 return -EINVAL;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002647 }
2648
2649 uint8_t comp_effecter_count = resp->comp_effecter_count;
2650
2651 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
2652 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
Tal Yacobif490a382024-05-31 09:57:36 +03002653 return -EBADMSG;
Tal Yacobia6fa5552024-05-05 16:57:38 +03002654 }
2655
2656 struct pldm_header_info header = { 0 };
2657 header.msg_type = PLDM_RESPONSE;
2658 header.instance = instance_id;
2659 header.pldm_type = PLDM_PLATFORM;
2660 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2661
Tal Yacobif490a382024-05-31 09:57:36 +03002662 rc = pack_pldm_header_errno(&header, &msg->hdr);
2663 if (rc < 0) {
Tal Yacobia6fa5552024-05-05 16:57:38 +03002664 return rc;
2665 }
2666
Tal Yacobif490a382024-05-31 09:57:36 +03002667 rc = pldm_msgbuf_init_errno(
2668 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
2669 msg->payload, payload_length);
Tal Yacobia6fa5552024-05-05 16:57:38 +03002670 if (rc) {
2671 return rc;
2672 }
2673
2674 pldm_msgbuf_insert(buf, resp->completion_code);
2675 pldm_msgbuf_insert(buf, comp_effecter_count);
2676
2677 for (i = 0, field = resp->field; i < comp_effecter_count;
2678 i++, field++) {
2679 pldm_msgbuf_insert(buf, field->effecter_op_state);
2680 pldm_msgbuf_insert(buf, field->pending_state);
2681 pldm_msgbuf_insert(buf, field->present_state);
2682 }
2683
2684 return pldm_msgbuf_destroy_consumed(buf);
2685}
Thu Nguyendacfa352024-06-22 09:53:15 +00002686
Thu Nguyen43cb4b52024-07-16 05:45:27 +00002687LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00002688int decode_entity_auxiliary_names_pdr(
2689 const void *data, size_t data_length,
2690 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
2691{
2692 struct pldm_msgbuf _buf;
2693 struct pldm_msgbuf *buf = &_buf;
2694 struct pldm_msgbuf _src;
2695 struct pldm_msgbuf *src = &_src;
2696 struct pldm_msgbuf _dst;
2697 struct pldm_msgbuf *dst = &_dst;
2698 size_t names_len = 0;
2699 void *names = NULL;
2700 int rc;
2701 int i;
2702
2703 /*
2704 * Alignment of auxiliary_name_data is an invariant as we statically assert
2705 * its behaviour in the header.
2706 */
2707 assert(!((uintptr_t)pdr->auxiliary_name_data &
2708 (alignof(pldm_utf16be) - 1)));
2709
2710 /* Reject any lengths that are obviously invalid */
2711 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
2712 return -EINVAL;
2713 }
2714
2715 rc = pldm_msgbuf_init_errno(
2716 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
2717 data_length);
2718 if (rc) {
2719 return rc;
2720 }
2721
2722 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr->hdr);
2723 if (rc) {
2724 return rc;
2725 }
2726
2727 rc = pldm_platform_pdr_hdr_validate(
2728 &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
2729 data_length);
2730 if (rc) {
2731 return rc;
2732 }
2733
2734 pldm_msgbuf_extract(buf, pdr->container.entity_type);
2735 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
2736 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
2737 pldm_msgbuf_extract(buf, pdr->shared_name_count);
2738 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
2739 if (rc < 0) {
2740 return rc;
2741 }
2742
2743 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
2744 if (rc < 0) {
2745 return rc;
2746 }
2747
2748 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
2749
2750 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
2751 pdr->auxiliary_name_data,
2752 pdr->auxiliary_name_data_size);
2753 if (rc < 0) {
2754 return rc;
2755 }
2756
2757 /*
2758 * Below we do two passes over the same region. This is to first pack the
2759 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
2760 * to maintain appropriate alignment.
2761 */
2762
2763 /* Initialise for the first pass to extract the UTF16-BE name strings */
2764 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
2765 if (rc < 0) {
2766 return rc;
2767 }
2768
2769 for (i = 0; i < pdr->name_string_count; i++) {
2770 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
2771 pldm_msgbuf_copy_string_utf16(dst, src);
2772 }
2773
2774 rc = pldm_msgbuf_destroy_consumed(src);
2775 if (rc < 0) {
2776 return rc;
2777 }
2778
2779 /* Reinitialise for the second pass to extract the ASCII tag strings */
2780 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
2781 if (rc < 0) {
2782 return rc;
2783 }
2784
2785 for (i = 0; i < pdr->name_string_count; i++) {
2786 pldm_msgbuf_copy_string_ascii(dst, src);
2787 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
2788 }
2789
2790 if ((rc = pldm_msgbuf_destroy(dst)) ||
2791 (rc = pldm_msgbuf_destroy(src)) ||
2792 (rc = pldm_msgbuf_destroy(buf))) {
2793 return rc;
2794 }
2795
2796 return 0;
2797}
2798
Thu Nguyen43cb4b52024-07-16 05:45:27 +00002799LIBPLDM_ABI_STABLE
Thu Nguyendacfa352024-06-22 09:53:15 +00002800int decode_pldm_entity_auxiliary_names_pdr_index(
2801 struct pldm_entity_auxiliary_names_pdr *pdr)
2802{
2803 struct pldm_msgbuf _buf;
2804 struct pldm_msgbuf *buf = &_buf;
2805 int rc;
2806 int i;
2807
2808 if (!pdr) {
2809 return -EINVAL;
2810 }
2811
2812 if (pdr->name_string_count == 0 && pdr->names) {
2813 return -EINVAL;
2814 }
2815
2816 if (pdr->name_string_count > 0 && !pdr->names) {
2817 return -EINVAL;
2818 }
2819
2820 if (pdr->name_string_count == 0) {
2821 return 0;
2822 }
2823
2824 /*
2825 * Minimum size is one NUL for each member of each entry
2826 *
2827 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
2828 * states the following:
2829 *
2830 * > A null-terminated ISO646 ASCII string ...
2831 * >
2832 * > special value: null string = 0x0000 = unspecified.
2833 *
2834 * Until proven otherwise we will assume the "0x0000" is a
2835 * misrepresentation of an ASCII NUL, and that ASCII NUL is
2836 * represented by a single byte.
2837 */
2838 rc = pldm_msgbuf_init_errno(
2839 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
2840 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
2841 if (rc) {
2842 return rc;
2843 }
2844
2845 for (i = 0; i < pdr->name_string_count; i++) {
2846 void *loc = NULL;
2847 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
2848 pdr->names[i].name = loc;
2849 }
2850
2851 for (i = 0; i < pdr->name_string_count; i++) {
2852 void *loc = NULL;
2853 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
2854 pdr->names[i].tag = loc;
2855 }
2856
2857 return pldm_msgbuf_destroy_consumed(buf);
2858}