blob: 75f94c5bab94cde908f685d67503d9611e6dcb32 [file] [log] [blame]
Patrick Williams691668f2023-11-01 08:19:10 -05001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
Andrew Jeffery7992eb82023-04-06 16:13:53 +09302#include "msgbuf.h"
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10303#include "msgbuf/platform.h"
4
5#include <libpldm/base.h>
6#include <libpldm/platform.h>
7#include <libpldm/pldm_types.h>
8
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <endian.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053010#include <stdint.h>
Thu Nguyen159a98b2022-11-02 10:00:10 +070011#include <stdlib.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093012#include <string.h>
13
Andrew Jeffery7992eb82023-04-06 16:13:53 +093014static int pldm_platform_pdr_hdr_validate(struct pldm_value_pdr_hdr *ctx,
15 size_t lower, size_t upper)
16{
17 if (ctx->length + sizeof(*ctx) < lower) {
18 return PLDM_ERROR_INVALID_LENGTH;
19 }
20
21 if (ctx->length > upper) {
22 return PLDM_ERROR_INVALID_LENGTH;
23 }
24
25 return PLDM_SUCCESS;
26}
Andrew Jeffery9c766792022-08-10 23:12:49 +093027
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093028LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +093029int encode_state_effecter_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093030 struct pldm_state_effecter_pdr *const effecter,
31 const size_t allocation_size,
32 const struct state_effecter_possible_states *const possible_states,
33 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093034{
35 // Encode possible states
36
37 size_t calculated_possible_states_size = 0;
38
39 {
40 char *states_ptr = (char *)possible_states;
41 char *const begin_states_ptr = states_ptr;
42
43 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
44 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093045 (struct state_effecter_possible_states *)
46 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093047
48 HTOLE16(states->state_set_id);
49
50 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093051 (sizeof(*states) - sizeof(states->states) +
52 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093053 }
54
55 calculated_possible_states_size = states_ptr - begin_states_ptr;
56 }
57
58 // Check lengths
59
60 if (possible_states_size != calculated_possible_states_size) {
61 *actual_size = 0;
62 return PLDM_ERROR;
63 }
64
65 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093066 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
67 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093068
69 if (allocation_size < *actual_size) {
70 *actual_size = 0;
71 return PLDM_ERROR_INVALID_LENGTH;
72 }
73
74 // Encode rest of PDR
75
76 effecter->hdr.version = 1;
77 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
78 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
79
80 memcpy(effecter->possible_states, possible_states,
81 possible_states_size);
82
83 // Convert effecter PDR body
84 HTOLE16(effecter->terminus_handle);
85 HTOLE16(effecter->effecter_id);
86 HTOLE16(effecter->entity_type);
87 HTOLE16(effecter->entity_instance);
88 HTOLE16(effecter->container_id);
89 HTOLE16(effecter->effecter_semantic_id);
90
91 // Convert header
92 HTOLE32(effecter->hdr.record_handle);
93 HTOLE16(effecter->hdr.record_change_num);
94 HTOLE16(effecter->hdr.length);
95
96 return PLDM_SUCCESS;
97}
98
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +093099LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930100int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930101 struct pldm_state_sensor_pdr *const sensor,
102 const size_t allocation_size,
103 const struct state_sensor_possible_states *const possible_states,
104 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930105{
106 // Encode possible states
107
108 size_t calculated_possible_states_size = 0;
109
110 {
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930111 char *states_ptr = (char *)possible_states;
112 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930113
114 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
115 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930116 (struct state_sensor_possible_states *)
117 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930118
119 HTOLE16(states->state_set_id);
120
121 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930122 (sizeof(*states) - sizeof(states->states) +
123 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930124 }
125
126 calculated_possible_states_size = states_ptr - begin_states_ptr;
127 }
128
129 // Check lengths
130
131 if (possible_states_size != calculated_possible_states_size) {
132 *actual_size = 0;
133 return PLDM_ERROR;
134 }
135
136 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
137 possible_states_size - sizeof(sensor->possible_states));
138
139 if (allocation_size < *actual_size) {
140 *actual_size = 0;
141 return PLDM_ERROR_INVALID_LENGTH;
142 }
143
144 // Encode rest of PDR
145
146 sensor->hdr.version = 1;
147 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
148 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
149
150 memcpy(sensor->possible_states, possible_states, possible_states_size);
151
152 // Convert sensor PDR body
153 HTOLE16(sensor->terminus_handle);
154 HTOLE16(sensor->sensor_id);
155 HTOLE16(sensor->entity_type);
156 HTOLE16(sensor->entity_instance);
157 HTOLE16(sensor->container_id);
158
159 // Convert header
160 HTOLE32(sensor->hdr.record_handle);
161 HTOLE16(sensor->hdr.record_change_num);
162 HTOLE16(sensor->hdr.length);
163
164 return PLDM_SUCCESS;
165}
166
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930167LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930168int encode_set_state_effecter_states_resp(uint8_t instance_id,
169 uint8_t completion_code,
170 struct pldm_msg *msg)
171{
172 if (msg == NULL) {
173 return PLDM_ERROR_INVALID_DATA;
174 }
175
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930176 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930177 header.msg_type = PLDM_RESPONSE;
178 header.instance = instance_id;
179 header.pldm_type = PLDM_PLATFORM;
180 header.command = PLDM_SET_STATE_EFFECTER_STATES;
181
182 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
183 if (rc != PLDM_SUCCESS) {
184 return rc;
185 }
186
187 msg->payload[0] = completion_code;
188
189 return PLDM_SUCCESS;
190}
191
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930192LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930193int encode_set_state_effecter_states_req(uint8_t instance_id,
194 uint16_t effecter_id,
195 uint8_t comp_effecter_count,
196 set_effecter_state_field *field,
197 struct pldm_msg *msg)
198{
199 if (msg == NULL) {
200 return PLDM_ERROR_INVALID_DATA;
201 }
202
203 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
204 field == NULL) {
205 return PLDM_ERROR_INVALID_DATA;
206 }
207
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930208 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930209 header.msg_type = PLDM_REQUEST;
210 header.instance = instance_id;
211 header.pldm_type = PLDM_PLATFORM;
212 header.command = PLDM_SET_STATE_EFFECTER_STATES;
213
214 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
215 if (rc != PLDM_SUCCESS) {
216 return rc;
217 }
218
219 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930220 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930221 effecter_id = htole16(effecter_id);
222 request->effecter_id = effecter_id;
223 request->comp_effecter_count = comp_effecter_count;
224 memcpy(request->field, field,
225 (sizeof(set_effecter_state_field) * comp_effecter_count));
226
227 return PLDM_SUCCESS;
228}
229
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930230LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930231int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
232 size_t payload_length,
233 uint8_t *completion_code)
234{
235 if (msg == NULL || completion_code == NULL) {
236 return PLDM_ERROR_INVALID_DATA;
237 }
238
239 *completion_code = msg->payload[0];
240 if (PLDM_SUCCESS != *completion_code) {
241 return PLDM_SUCCESS;
242 }
243
244 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
245 return PLDM_ERROR_INVALID_LENGTH;
246 }
247
248 return PLDM_SUCCESS;
249}
250
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930251#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930252LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930253int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
254 size_t payload_length,
255 uint16_t *effecter_id,
256 uint8_t *comp_effecter_count,
257 set_effecter_state_field *field)
258{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930259 struct pldm_msgbuf _buf;
260 struct pldm_msgbuf *buf = &_buf;
261 int rc;
262 int i;
263
Andrew Jeffery9c766792022-08-10 23:12:49 +0930264 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
265 field == NULL) {
266 return PLDM_ERROR_INVALID_DATA;
267 }
268
269 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
270 return PLDM_ERROR_INVALID_LENGTH;
271 }
272
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930273 rc = pldm_msgbuf_init(buf, PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
274 msg->payload, payload_length);
275 if (rc) {
276 return rc;
277 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930278
Andrew Jeffery66c77232024-04-24 11:42:02 +0930279 pldm_msgbuf_extract_p(buf, effecter_id);
280 pldm_msgbuf_extract_p(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930281
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930282 if (*comp_effecter_count > 8) {
283 return PLDM_ERROR_INVALID_DATA;
284 }
285
286 for (i = 0; i < *comp_effecter_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930287 pldm_msgbuf_extract(buf, field[i].set_request);
288 pldm_msgbuf_extract(buf, field[i].effecter_state);
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930289 }
290
291 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930292}
293
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930294LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930295int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
296 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
297 uint8_t *transfer_op_flag, uint16_t *request_cnt,
298 uint16_t *record_chg_num)
299{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930300 struct pldm_msgbuf _buf;
301 struct pldm_msgbuf *buf = &_buf;
302 int rc;
303
Andrew Jeffery9c766792022-08-10 23:12:49 +0930304 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
305 transfer_op_flag == NULL || request_cnt == NULL ||
306 record_chg_num == NULL) {
307 return PLDM_ERROR_INVALID_DATA;
308 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930309
Andrew Jeffery9c766792022-08-10 23:12:49 +0930310 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
311 return PLDM_ERROR_INVALID_LENGTH;
312 }
313
Andrew Jeffery891781e2023-04-04 11:04:18 +0930314 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
315 payload_length);
316 if (rc) {
317 return rc;
318 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930319
Andrew Jeffery66c77232024-04-24 11:42:02 +0930320 pldm_msgbuf_extract_p(buf, record_hndl);
321 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
322 pldm_msgbuf_extract_p(buf, transfer_op_flag);
323 pldm_msgbuf_extract_p(buf, request_cnt);
324 pldm_msgbuf_extract_p(buf, record_chg_num);
Andrew Jeffery891781e2023-04-04 11:04:18 +0930325
326 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930327}
328
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930329LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930330int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
331 uint32_t next_record_hndl,
332 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
333 uint16_t resp_cnt, const uint8_t *record_data,
334 uint8_t transfer_crc, struct pldm_msg *msg)
335{
336 if (msg == NULL) {
337 return PLDM_ERROR_INVALID_DATA;
338 }
339
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930340 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930341 header.msg_type = PLDM_RESPONSE;
342 header.instance = instance_id;
343 header.pldm_type = PLDM_PLATFORM;
344 header.command = PLDM_GET_PDR;
345
346 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
347 if (rc != PLDM_SUCCESS) {
348 return rc;
349 }
350
351 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930352 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930353 response->completion_code = completion_code;
354
355 if (response->completion_code == PLDM_SUCCESS) {
356 response->next_record_handle = htole32(next_record_hndl);
357 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930358 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930359 response->transfer_flag = transfer_flag;
360 response->response_count = htole16(resp_cnt);
361 if (record_data != NULL && resp_cnt > 0) {
362 memcpy(response->record_data, record_data, resp_cnt);
363 }
364 if (transfer_flag == PLDM_END) {
365 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930366 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
367 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930368 *dst = transfer_crc;
369 }
370 }
371
372 return PLDM_SUCCESS;
373}
374
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930375LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930376int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930377 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
378 const uint8_t *update_time, const uint8_t *oem_update_time,
379 uint32_t record_count, uint32_t repository_size,
380 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
381 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930382{
383 if (msg == NULL) {
384 return PLDM_ERROR_INVALID_DATA;
385 }
386
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930387 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930388 header.msg_type = PLDM_RESPONSE;
389 header.instance = instance_id;
390 header.pldm_type = PLDM_PLATFORM;
391 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
392
393 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
394 if (rc != PLDM_SUCCESS) {
395 return rc;
396 }
397
398 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930399 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930400 response->completion_code = completion_code;
401
402 if (response->completion_code == PLDM_SUCCESS) {
403 response->repository_state = repository_state;
404 if (update_time != NULL) {
405 memcpy(response->update_time, update_time,
406 PLDM_TIMESTAMP104_SIZE);
407 }
408 if (oem_update_time != NULL) {
409 memcpy(response->oem_update_time, oem_update_time,
410 PLDM_TIMESTAMP104_SIZE);
411 }
412 response->record_count = htole32(record_count);
413 response->repository_size = htole32(repository_size);
414 response->largest_record_size = htole32(largest_record_size);
415 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930416 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930417 }
418
419 return PLDM_SUCCESS;
420}
421
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930422LIBPLDM_ABI_STABLE
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800423int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930424 const struct pldm_msg *msg, size_t payload_length,
425 uint8_t *completion_code, uint8_t *repository_state,
426 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
427 uint32_t *repository_size, uint32_t *largest_record_size,
428 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800429{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930430 struct pldm_msgbuf _buf;
431 struct pldm_msgbuf *buf = &_buf;
432 int rc;
433
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800434 if (msg == NULL || completion_code == NULL ||
435 repository_state == NULL || update_time == NULL ||
436 oem_update_time == NULL || record_count == NULL ||
437 repository_size == NULL || largest_record_size == NULL ||
438 data_transfer_handle_timeout == NULL) {
439 return PLDM_ERROR_INVALID_DATA;
440 }
441
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930442 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
443 msg->payload, payload_length);
444 if (rc) {
445 return rc;
446 }
447
Andrew Jeffery66c77232024-04-24 11:42:02 +0930448 pldm_msgbuf_extract_p(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800449 if (PLDM_SUCCESS != *completion_code) {
450 return PLDM_SUCCESS;
451 }
452
Andrew Jeffery66c77232024-04-24 11:42:02 +0930453 pldm_msgbuf_extract_p(buf, repository_state);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800454 if (*repository_state > PLDM_FAILED) {
455 return PLDM_ERROR_INVALID_DATA;
456 }
457
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930458 pldm_msgbuf_extract_array(buf, update_time, PLDM_TIMESTAMP104_SIZE);
459 pldm_msgbuf_extract_array(buf, oem_update_time, PLDM_TIMESTAMP104_SIZE);
Andrew Jeffery66c77232024-04-24 11:42:02 +0930460 pldm_msgbuf_extract_p(buf, record_count);
461 pldm_msgbuf_extract_p(buf, repository_size);
462 pldm_msgbuf_extract_p(buf, largest_record_size);
463 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800464
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930465 return pldm_msgbuf_destroy(buf);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800466}
467
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930468LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930469int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
470 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
471 uint16_t request_cnt, uint16_t record_chg_num,
472 struct pldm_msg *msg, size_t payload_length)
473{
474 if (msg == NULL) {
475 return PLDM_ERROR_INVALID_DATA;
476 }
477
478 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
479 return PLDM_ERROR_INVALID_LENGTH;
480 }
481
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930482 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930483 header.msg_type = PLDM_REQUEST;
484 header.instance = instance_id;
485 header.pldm_type = PLDM_PLATFORM;
486 header.command = PLDM_GET_PDR;
487
488 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
489 if (rc != PLDM_SUCCESS) {
490 return rc;
491 }
492
493 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930494 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930495 request->record_handle = htole32(record_hndl);
496 request->data_transfer_handle = htole32(data_transfer_hndl);
497 request->transfer_op_flag = transfer_op_flag;
498 request->request_count = htole16(request_cnt);
499 request->record_change_number = htole16(record_chg_num);
500
501 return PLDM_SUCCESS;
502}
503
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930504LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930505int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
506 uint8_t *completion_code, uint32_t *next_record_hndl,
507 uint32_t *next_data_transfer_hndl,
508 uint8_t *transfer_flag, uint16_t *resp_cnt,
509 uint8_t *record_data, size_t record_data_length,
510 uint8_t *transfer_crc)
511{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930512 struct pldm_msgbuf _buf;
513 struct pldm_msgbuf *buf = &_buf;
514 int rc;
515
Andrew Jeffery9c766792022-08-10 23:12:49 +0930516 if (msg == NULL || completion_code == NULL ||
517 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
518 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
519 return PLDM_ERROR_INVALID_DATA;
520 }
521
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930522 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
523 payload_length);
524 if (rc) {
525 return rc;
526 }
527
Andrew Jeffery66c77232024-04-24 11:42:02 +0930528 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930529 if (PLDM_SUCCESS != *completion_code) {
530 return PLDM_SUCCESS;
531 }
532
Andrew Jeffery66c77232024-04-24 11:42:02 +0930533 pldm_msgbuf_extract_p(buf, next_record_hndl);
534 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
535 pldm_msgbuf_extract_p(buf, transfer_flag);
536 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930537 if (rc) {
538 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930539 }
540
541 if (*resp_cnt > 0 && record_data != NULL) {
542 if (record_data_length < *resp_cnt) {
543 return PLDM_ERROR_INVALID_LENGTH;
544 }
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930545 pldm_msgbuf_extract_array(buf, record_data, *resp_cnt);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930546 }
547
548 if (*transfer_flag == PLDM_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930549 pldm_msgbuf_extract_p(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930550 }
551
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930552 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930553}
554
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930555LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930556int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
557 size_t payload_length,
558 uint16_t *effecter_id,
559 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930560 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930561{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930562 struct pldm_msgbuf _buf;
563 struct pldm_msgbuf *buf = &_buf;
564 int rc;
565
Andrew Jeffery9c766792022-08-10 23:12:49 +0930566 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
567 effecter_value == NULL) {
568 return PLDM_ERROR_INVALID_DATA;
569 }
570
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930571 rc = pldm_msgbuf_init(buf,
572 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
573 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930574 if (rc) {
575 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930576 }
577
Andrew Jeffery66c77232024-04-24 11:42:02 +0930578 pldm_msgbuf_extract_p(buf, effecter_id);
579 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930580 if (rc) {
581 return PLDM_ERROR_INVALID_DATA;
582 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930583
584 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
585 return PLDM_ERROR_INVALID_DATA;
586 }
587
Andrew Jeffery3884c442023-04-12 11:13:24 +0930588 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
589 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930590
Andrew Jeffery3884c442023-04-12 11:13:24 +0930591 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930592}
593
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930594LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930595int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
596 uint8_t completion_code,
597 struct pldm_msg *msg,
598 size_t payload_length)
599{
600 if (msg == NULL) {
601 return PLDM_ERROR_INVALID_DATA;
602 }
603
604 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
605 return PLDM_ERROR_INVALID_LENGTH;
606 }
607
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930608 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930609 header.msg_type = PLDM_RESPONSE;
610 header.instance = instance_id;
611 header.pldm_type = PLDM_PLATFORM;
612 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
613
614 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
615 if (rc != PLDM_SUCCESS) {
616 return rc;
617 }
618
619 msg->payload[0] = completion_code;
620
621 return rc;
622}
623
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930624LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930625int encode_set_numeric_effecter_value_req(uint8_t instance_id,
626 uint16_t effecter_id,
627 uint8_t effecter_data_size,
628 const uint8_t *effecter_value,
629 struct pldm_msg *msg,
630 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930631{
632 if (msg == NULL || effecter_value == NULL) {
633 return PLDM_ERROR_INVALID_DATA;
634 }
635
636 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
637 return PLDM_ERROR_INVALID_DATA;
638 }
639
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930640 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930641 header.msg_type = PLDM_REQUEST;
642 header.instance = instance_id;
643 header.pldm_type = PLDM_PLATFORM;
644 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
645
646 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
647 if (rc != PLDM_SUCCESS) {
648 return rc;
649 }
650
651 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930652 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930653 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
654 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
655 if (payload_length !=
656 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
657 return PLDM_ERROR_INVALID_LENGTH;
658 }
659 request->effecter_value[0] = *effecter_value;
660 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
661 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
662 if (payload_length !=
663 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
664 return PLDM_ERROR_INVALID_LENGTH;
665 }
666
667 uint16_t val = *(uint16_t *)(effecter_value);
668 val = htole16(val);
669 memcpy(request->effecter_value, &val, sizeof(uint16_t));
670
671 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
672 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
673 if (payload_length !=
674 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
675 return PLDM_ERROR_INVALID_LENGTH;
676 }
677
678 uint32_t val = *(uint32_t *)(effecter_value);
679 val = htole32(val);
680 memcpy(request->effecter_value, &val, sizeof(uint32_t));
681 }
682
683 request->effecter_id = htole16(effecter_id);
684 request->effecter_data_size = effecter_data_size;
685
686 return PLDM_SUCCESS;
687}
688
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930689LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930690int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
691 size_t payload_length,
692 uint8_t *completion_code)
693{
694 if (msg == NULL || completion_code == NULL) {
695 return PLDM_ERROR_INVALID_DATA;
696 }
697
698 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
699 return PLDM_ERROR_INVALID_LENGTH;
700 }
701
702 *completion_code = msg->payload[0];
703
704 return PLDM_SUCCESS;
705}
706
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930707LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930708int encode_get_state_sensor_readings_resp(uint8_t instance_id,
709 uint8_t completion_code,
710 uint8_t comp_sensor_count,
711 get_sensor_state_field *field,
712 struct pldm_msg *msg)
713{
714 if (msg == NULL) {
715 return PLDM_ERROR_INVALID_DATA;
716 }
717
718 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
719 return PLDM_ERROR_INVALID_DATA;
720 }
721
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930722 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930723 header.msg_type = PLDM_RESPONSE;
724 header.instance = instance_id;
725 header.pldm_type = PLDM_PLATFORM;
726 header.command = PLDM_GET_STATE_SENSOR_READINGS;
727
728 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
729 if (rc != PLDM_SUCCESS) {
730 return rc;
731 }
732
733 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930734 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930735
736 response->completion_code = completion_code;
737 response->comp_sensor_count = comp_sensor_count;
738 memcpy(response->field, field,
739 (sizeof(get_sensor_state_field) * comp_sensor_count));
740
741 return PLDM_SUCCESS;
742}
743
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930744LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930745int encode_get_state_sensor_readings_req(uint8_t instance_id,
746 uint16_t sensor_id,
747 bitfield8_t sensor_rearm,
748 uint8_t reserved, struct pldm_msg *msg)
749{
750 if (msg == NULL) {
751 return PLDM_ERROR_INVALID_DATA;
752 }
753
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930754 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930755 header.msg_type = PLDM_REQUEST;
756 header.instance = instance_id;
757 header.pldm_type = PLDM_PLATFORM;
758 header.command = PLDM_GET_STATE_SENSOR_READINGS;
759
760 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
761 if (rc != PLDM_SUCCESS) {
762 return rc;
763 }
764
765 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930766 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930767
768 request->sensor_id = htole16(sensor_id);
769 request->reserved = reserved;
770 request->sensor_rearm = sensor_rearm;
771
772 return PLDM_SUCCESS;
773}
774
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930775LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930776int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
777 size_t payload_length,
778 uint8_t *completion_code,
779 uint8_t *comp_sensor_count,
780 get_sensor_state_field *field)
781{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930782 struct pldm_msgbuf _buf;
783 struct pldm_msgbuf *buf = &_buf;
784 uint8_t i;
785 int rc;
786
Andrew Jeffery9c766792022-08-10 23:12:49 +0930787 if (msg == NULL || completion_code == NULL ||
788 comp_sensor_count == NULL || field == NULL) {
789 return PLDM_ERROR_INVALID_DATA;
790 }
791
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930792 rc = pldm_msgbuf_init(buf,
793 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
794 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930795 if (rc) {
796 return rc;
797 }
798
Andrew Jeffery66c77232024-04-24 11:42:02 +0930799 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930800 if (rc) {
801 return rc;
802 }
803
Andrew Jeffery9c766792022-08-10 23:12:49 +0930804 if (PLDM_SUCCESS != *completion_code) {
805 return PLDM_SUCCESS;
806 }
807
Andrew Jeffery66c77232024-04-24 11:42:02 +0930808 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930809 if (rc) {
810 return rc;
811 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930812
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930813 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930814 return PLDM_ERROR_INVALID_DATA;
815 }
816
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930817 for (i = 0; i < *comp_sensor_count; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +0930818 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
819 pldm_msgbuf_extract(buf, field[i].present_state);
820 pldm_msgbuf_extract(buf, field[i].previous_state);
821 pldm_msgbuf_extract(buf, field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930822 }
823
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930824 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930825}
826
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930827LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930828int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
829 size_t payload_length,
830 uint16_t *sensor_id,
831 bitfield8_t *sensor_rearm,
832 uint8_t *reserved)
833{
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930834 struct pldm_msgbuf _buf;
835 struct pldm_msgbuf *buf = &_buf;
836 int rc;
837
Andrew Jeffery9c766792022-08-10 23:12:49 +0930838 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
839 return PLDM_ERROR_INVALID_DATA;
840 }
841
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930842 rc = pldm_msgbuf_init(buf, PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
843 msg->payload, payload_length);
844 if (rc) {
845 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930846 }
847
Andrew Jeffery66c77232024-04-24 11:42:02 +0930848 pldm_msgbuf_extract_p(buf, sensor_id);
849 pldm_msgbuf_extract(buf, sensor_rearm->byte);
850 pldm_msgbuf_extract_p(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930851
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930852 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930853}
854
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930855LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930856int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930857 struct pldm_sensor_event_data *const event_data,
858 const size_t event_data_size, const uint16_t sensor_id,
859 const enum sensor_event_class_states sensor_event_class,
860 const uint8_t sensor_offset, const uint8_t event_state,
861 const uint8_t previous_event_state,
862 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930863{
864 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930865 (sizeof(*event_data) - sizeof(event_data->event_class) +
866 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930867
868 if (!event_data) {
869 return PLDM_SUCCESS;
870 }
871
872 if (event_data_size < *actual_event_data_size) {
873 *actual_event_data_size = 0;
874 return PLDM_ERROR_INVALID_LENGTH;
875 }
876
877 event_data->sensor_id = htole16(sensor_id);
878 event_data->sensor_event_class_type = sensor_event_class;
879
880 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930881 (struct pldm_sensor_event_state_sensor_state *)
882 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930883
884 state_data->sensor_offset = sensor_offset;
885 state_data->event_state = event_state;
886 state_data->previous_event_state = previous_event_state;
887
888 return PLDM_SUCCESS;
889}
890
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930891LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930892int decode_platform_event_message_req(const struct pldm_msg *msg,
893 size_t payload_length,
894 uint8_t *format_version, uint8_t *tid,
895 uint8_t *event_class,
896 size_t *event_data_offset)
897{
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930898 struct pldm_msgbuf _buf;
899 struct pldm_msgbuf *buf = &_buf;
900 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930901
902 if (msg == NULL || format_version == NULL || tid == NULL ||
903 event_class == NULL || event_data_offset == NULL) {
904 return PLDM_ERROR_INVALID_DATA;
905 }
906
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930907 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
908 msg->payload, payload_length);
909 if (rc) {
910 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930911 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930912
Andrew Jeffery66c77232024-04-24 11:42:02 +0930913 pldm_msgbuf_extract_p(buf, format_version);
914 pldm_msgbuf_extract_p(buf, tid);
915 pldm_msgbuf_extract_p(buf, event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930916 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930917 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930918
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930919 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930920}
921
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930922LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700923int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930924 const struct pldm_msg *msg, size_t payload_length,
925 uint8_t *format_version, uint8_t *transfer_operation_flag,
926 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700927{
928 struct pldm_msgbuf _buf;
929 struct pldm_msgbuf *buf = &_buf;
930 int rc;
931
932 if (msg == NULL) {
933 return PLDM_ERROR_INVALID_DATA;
934 }
935
936 rc = pldm_msgbuf_init(buf,
937 PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
938 msg->payload, payload_length);
939 if (rc) {
940 return rc;
941 }
942
Andrew Jeffery66c77232024-04-24 11:42:02 +0930943 pldm_msgbuf_extract_p(buf, format_version);
944 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700945 if (rc) {
946 return rc;
947 }
948 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
949 return PLDM_ERROR_INVALID_DATA;
950 }
951
Andrew Jeffery66c77232024-04-24 11:42:02 +0930952 pldm_msgbuf_extract_p(buf, data_transfer_handle);
953 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700954 if (rc) {
955 return rc;
956 }
957
958 if (!(((*transfer_operation_flag == PLDM_GET_NEXTPART) &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600959 (*event_id_to_acknowledge == 0xffff)) ||
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700960 ((*transfer_operation_flag == PLDM_GET_FIRSTPART) &&
961 (*event_id_to_acknowledge == 0x000)) ||
962 (*transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY))) {
963 return PLDM_ERROR_INVALID_DATA;
964 }
965
966 return pldm_msgbuf_destroy(buf);
967}
968
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +0930969LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +0930970int encode_platform_event_message_resp(uint8_t instance_id,
971 uint8_t completion_code,
972 uint8_t platform_event_status,
973 struct pldm_msg *msg)
974{
975 if (msg == NULL) {
976 return PLDM_ERROR_INVALID_DATA;
977 }
978
979 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
980 return PLDM_ERROR_INVALID_DATA;
981 }
982
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930983 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930984 header.msg_type = PLDM_RESPONSE;
985 header.instance = instance_id;
986 header.pldm_type = PLDM_PLATFORM;
987 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
988
989 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
990 if (rc != PLDM_SUCCESS) {
991 return rc;
992 }
993
994 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930995 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930996 response->completion_code = completion_code;
997 response->platform_event_status = platform_event_status;
998
999 return PLDM_SUCCESS;
1000}
1001
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301002LIBPLDM_ABI_STABLE
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001003int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301004 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1005 uint16_t event_id, uint32_t next_data_transfer_handle,
1006 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1007 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1008 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001009{
1010 struct pldm_msgbuf _buf;
1011 struct pldm_msgbuf *buf = &_buf;
1012 int rc;
1013
1014 if (!msg) {
1015 return PLDM_ERROR_INVALID_DATA;
1016 }
1017
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301018 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001019 header.msg_type = PLDM_RESPONSE;
1020 header.instance = instance_id;
1021 header.pldm_type = PLDM_PLATFORM;
1022 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1023
1024 rc = pack_pldm_header(&header, &(msg->hdr));
1025 if (rc != PLDM_SUCCESS) {
1026 return rc;
1027 }
1028
1029 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301030 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1031 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001032 if (rc) {
1033 return rc;
1034 }
1035
1036 pldm_msgbuf_insert(buf, completion_code);
1037 pldm_msgbuf_insert(buf, tid);
1038 pldm_msgbuf_insert(buf, event_id);
1039
1040 if (event_id == 0xffff || event_id == 0x0000) {
1041 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1042 payload_length) {
1043 return PLDM_ERROR_INVALID_LENGTH;
1044 }
1045 return pldm_msgbuf_destroy(buf);
1046 }
1047
1048 if ((event_data == NULL) && (event_data_size > 0)) {
1049 return PLDM_ERROR_INVALID_DATA;
1050 }
1051
1052 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1053 pldm_msgbuf_insert(buf, transfer_flag);
1054 pldm_msgbuf_insert(buf, event_class);
1055 pldm_msgbuf_insert(buf, event_data_size);
1056
1057 if ((event_data_size > 0) && event_data) {
1058 pldm_msgbuf_insert_array(buf, event_data, event_data_size);
1059 }
1060
1061 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1062 pldm_msgbuf_insert(buf, checksum);
1063 }
1064
1065 return pldm_msgbuf_destroy(buf);
1066}
1067
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301068LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301069int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301070 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1071 uint8_t event_class, const uint8_t *event_data,
1072 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301073
1074{
1075 if (format_version != 1) {
1076 return PLDM_ERROR_INVALID_DATA;
1077 }
1078
1079 if (msg == NULL || event_data == NULL) {
1080 return PLDM_ERROR_INVALID_DATA;
1081 }
1082
1083 if (event_data_length == 0) {
1084 return PLDM_ERROR_INVALID_DATA;
1085 }
1086
1087 if (payload_length !=
1088 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1089 return PLDM_ERROR_INVALID_LENGTH;
1090 }
1091
1092 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001093 !(event_class >= 0xf0 && event_class <= 0xfe)) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301094 return PLDM_ERROR_INVALID_DATA;
1095 }
1096
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301097 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301098 header.msg_type = PLDM_REQUEST;
1099 header.instance = instance_id;
1100 header.pldm_type = PLDM_PLATFORM;
1101 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1102
1103 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1104 if (rc != PLDM_SUCCESS) {
1105 return rc;
1106 }
1107
1108 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301109 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301110 request->format_version = format_version;
1111 request->tid = tid;
1112 request->event_class = event_class;
1113 memcpy(request->event_data, event_data, event_data_length);
1114
1115 return PLDM_SUCCESS;
1116}
1117
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301118LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301119int decode_platform_event_message_resp(const struct pldm_msg *msg,
1120 size_t payload_length,
1121 uint8_t *completion_code,
1122 uint8_t *platform_event_status)
1123{
Andrew Jefferye5011772023-04-13 12:06:22 +09301124 struct pldm_msgbuf _buf;
1125 struct pldm_msgbuf *buf = &_buf;
1126 int rc;
1127
Andrew Jeffery9c766792022-08-10 23:12:49 +09301128 if (msg == NULL || completion_code == NULL ||
1129 platform_event_status == NULL) {
1130 return PLDM_ERROR_INVALID_DATA;
1131 }
1132
Andrew Jefferye5011772023-04-13 12:06:22 +09301133 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1134 msg->payload, payload_length);
1135 if (rc) {
1136 return rc;
1137 }
1138
Andrew Jeffery66c77232024-04-24 11:42:02 +09301139 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jefferye5011772023-04-13 12:06:22 +09301140 if (rc) {
1141 return rc;
1142 }
1143
Andrew Jeffery9c766792022-08-10 23:12:49 +09301144 if (PLDM_SUCCESS != *completion_code) {
1145 return PLDM_SUCCESS;
1146 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301147
Andrew Jeffery66c77232024-04-24 11:42:02 +09301148 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
Andrew Jefferye5011772023-04-13 12:06:22 +09301149 if (rc) {
1150 return rc;
1151 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301152
1153 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1154 return PLDM_ERROR_INVALID_DATA;
1155 }
1156
Andrew Jefferye5011772023-04-13 12:06:22 +09301157 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301158}
1159
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301160LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301161int encode_event_message_buffer_size_req(uint8_t instance_id,
1162 uint16_t event_receiver_max_buffer_size,
1163 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001164{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301165 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001166 header.msg_type = PLDM_REQUEST;
1167 header.instance = instance_id;
1168 header.pldm_type = PLDM_PLATFORM;
1169 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1170
1171 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1172 if (rc != PLDM_SUCCESS) {
1173 return rc;
1174 }
1175
1176 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301177 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001178 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301179 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001180
1181 return PLDM_SUCCESS;
1182}
1183
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301184LIBPLDM_ABI_STABLE
Dung Caod6ae8982022-11-02 10:00:10 +07001185int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1186 size_t payload_length,
1187 uint8_t *completion_code,
1188 uint16_t *terminus_max_buffer_size)
1189{
Andrew Jeffery11126902023-04-13 12:12:10 +09301190 struct pldm_msgbuf _buf;
1191 struct pldm_msgbuf *buf = &_buf;
1192 int rc;
1193
Dung Caod6ae8982022-11-02 10:00:10 +07001194 if (msg == NULL || completion_code == NULL ||
1195 terminus_max_buffer_size == NULL) {
1196 return PLDM_ERROR_INVALID_DATA;
1197 }
1198
Andrew Jeffery11126902023-04-13 12:12:10 +09301199 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1200 msg->payload, payload_length);
1201 if (rc) {
1202 return rc;
1203 }
1204
Andrew Jeffery66c77232024-04-24 11:42:02 +09301205 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery11126902023-04-13 12:12:10 +09301206 if (rc) {
1207 return rc;
1208 }
1209
Dung Caod6ae8982022-11-02 10:00:10 +07001210 if (PLDM_SUCCESS != *completion_code) {
1211 return PLDM_SUCCESS;
1212 }
Dung Caod6ae8982022-11-02 10:00:10 +07001213
Andrew Jeffery66c77232024-04-24 11:42:02 +09301214 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001215
Andrew Jeffery11126902023-04-13 12:12:10 +09301216 return pldm_msgbuf_destroy_consumed(buf);
Dung Caod6ae8982022-11-02 10:00:10 +07001217}
1218
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301219LIBPLDM_ABI_STABLE
Dung Cao1bf8c872022-11-29 05:32:58 +07001220int encode_event_message_supported_req(uint8_t instance_id,
1221 uint8_t format_version,
1222 struct pldm_msg *msg)
1223{
1224 if (format_version != 1) {
1225 return PLDM_ERROR_INVALID_DATA;
1226 }
1227
1228 if (msg == NULL) {
1229 return PLDM_ERROR_INVALID_DATA;
1230 }
1231
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301232 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001233 header.msg_type = PLDM_REQUEST;
1234 header.instance = instance_id;
1235 header.pldm_type = PLDM_PLATFORM;
1236 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1237
1238 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1239 if (rc != PLDM_SUCCESS) {
1240 return rc;
1241 }
1242
1243 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301244 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001245 request->format_version = format_version;
1246
1247 return PLDM_SUCCESS;
1248}
1249
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301250LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301251int decode_event_message_supported_resp(const struct pldm_msg *msg,
1252 size_t payload_length,
1253 uint8_t *completion_code,
1254 uint8_t *synchrony_config,
1255 bitfield8_t *synchrony_config_support,
1256 uint8_t *number_event_class_returned,
1257 uint8_t *event_class,
1258 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001259{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301260 struct pldm_msgbuf _buf;
1261 struct pldm_msgbuf *buf = &_buf;
1262 int i;
1263 int rc;
1264
Dung Cao1bf8c872022-11-29 05:32:58 +07001265 if (msg == NULL || completion_code == NULL ||
1266 synchrony_config == NULL || synchrony_config_support == NULL ||
1267 number_event_class_returned == NULL || event_class == NULL) {
1268 return PLDM_ERROR_INVALID_DATA;
1269 }
1270
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301271 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1272 msg->payload, payload_length);
1273 if (rc) {
1274 return rc;
1275 }
1276
Andrew Jeffery66c77232024-04-24 11:42:02 +09301277 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301278 if (rc) {
1279 return rc;
1280 }
1281
Dung Cao1bf8c872022-11-29 05:32:58 +07001282 if (PLDM_SUCCESS != *completion_code) {
1283 return PLDM_SUCCESS;
1284 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301285
Andrew Jeffery66c77232024-04-24 11:42:02 +09301286 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301287 if (rc) {
1288 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001289 }
1290
Dung Cao1bf8c872022-11-29 05:32:58 +07001291 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1292 return PLDM_ERROR_INVALID_DATA;
1293 }
1294
Andrew Jeffery66c77232024-04-24 11:42:02 +09301295 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001296
Andrew Jeffery66c77232024-04-24 11:42:02 +09301297 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301298 if (rc) {
1299 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001300 }
1301
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301302 if (*number_event_class_returned == 0) {
1303 return pldm_msgbuf_destroy(buf);
1304 }
1305
1306 if (event_class_count < *number_event_class_returned) {
1307 return PLDM_ERROR_INVALID_LENGTH;
1308 }
1309
1310 for (i = 0; i < *number_event_class_returned; i++) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09301311 pldm_msgbuf_extract(buf, event_class[i]);
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301312 }
1313
1314 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao1bf8c872022-11-29 05:32:58 +07001315}
1316
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301317LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301318int decode_sensor_event_data(const uint8_t *event_data,
1319 size_t event_data_length, uint16_t *sensor_id,
1320 uint8_t *sensor_event_class_type,
1321 size_t *event_class_data_offset)
1322{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301323 struct pldm_msgbuf _buf;
1324 struct pldm_msgbuf *buf = &_buf;
1325 int rc;
1326
1327 rc = pldm_msgbuf_init(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1328 event_data, event_data_length);
1329 if (rc) {
1330 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301331 }
1332
1333 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301334 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301335
Andrew Jeffery66c77232024-04-24 11:42:02 +09301336 pldm_msgbuf_extract_p(buf, sensor_id);
1337 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301338 if (rc) {
1339 return rc;
1340 }
1341
1342 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301343 if (event_class_data_length !=
1344 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1345 return PLDM_ERROR_INVALID_LENGTH;
1346 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301347 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301348 if (event_class_data_length !=
1349 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1350 return PLDM_ERROR_INVALID_LENGTH;
1351 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301352 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301353 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301354 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301355 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301356 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301357 return PLDM_ERROR_INVALID_LENGTH;
1358 }
1359 } else {
1360 return PLDM_ERROR_INVALID_DATA;
1361 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301362
Andrew Jeffery9c766792022-08-10 23:12:49 +09301363 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301364 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301365
1366 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301367}
1368
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301369LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301370int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1371 uint8_t *present_op_state, uint8_t *previous_op_state)
1372{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301373 struct pldm_msgbuf _buf;
1374 struct pldm_msgbuf *buf = &_buf;
1375 int rc;
1376
1377 if (present_op_state == NULL || previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301378 return PLDM_ERROR_INVALID_DATA;
1379 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301380
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301381 rc = pldm_msgbuf_init(buf,
1382 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH,
1383 sensor_data, sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301384 if (rc) {
1385 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301386 }
1387
Andrew Jeffery66c77232024-04-24 11:42:02 +09301388 pldm_msgbuf_extract_p(buf, present_op_state);
1389 pldm_msgbuf_extract_p(buf, previous_op_state);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301390
1391 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301392}
1393
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301394LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301395int decode_state_sensor_data(const uint8_t *sensor_data,
1396 size_t sensor_data_length, uint8_t *sensor_offset,
1397 uint8_t *event_state,
1398 uint8_t *previous_event_state)
1399{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301400 struct pldm_msgbuf _buf;
1401 struct pldm_msgbuf *buf = &_buf;
1402 int rc;
1403
1404 if (sensor_offset == NULL || event_state == NULL ||
1405 previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301406 return PLDM_ERROR_INVALID_DATA;
1407 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301408
1409 rc = pldm_msgbuf_init(buf,
1410 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1411 sensor_data, sensor_data_length);
1412 if (rc) {
1413 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301414 }
1415
Andrew Jeffery66c77232024-04-24 11:42:02 +09301416 pldm_msgbuf_extract_p(buf, sensor_offset);
1417 pldm_msgbuf_extract_p(buf, event_state);
1418 pldm_msgbuf_extract_p(buf, previous_event_state);
Andrew Jeffery422790b2023-04-13 15:03:47 +09301419
1420 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301421}
1422
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301423LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301424int decode_numeric_sensor_data(const uint8_t *sensor_data,
1425 size_t sensor_data_length, uint8_t *event_state,
1426 uint8_t *previous_event_state,
1427 uint8_t *sensor_data_size,
1428 uint32_t *present_reading)
1429{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301430 struct pldm_msgbuf _buf;
1431 struct pldm_msgbuf *buf = &_buf;
1432 int rc;
1433
1434 if (sensor_data_size == NULL || event_state == NULL ||
1435 previous_event_state == NULL || present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301436 return PLDM_ERROR_INVALID_DATA;
1437 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301438
1439 if (sensor_data_length >
1440 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301441 return PLDM_ERROR_INVALID_LENGTH;
1442 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301443
Andrew Jeffery155317e2023-04-13 18:36:51 +09301444 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301445 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1446 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301447 if (rc) {
1448 return rc;
1449 }
1450
Andrew Jeffery66c77232024-04-24 11:42:02 +09301451 pldm_msgbuf_extract_p(buf, event_state);
1452 pldm_msgbuf_extract_p(buf, previous_event_state);
1453 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301454 if (rc) {
1455 return rc;
1456 }
1457
1458 /*
1459 * The implementation below is bonkers, but it's because the function
1460 * prototype is bonkers. The `present_reading` argument should have been
1461 * a tagged union.
1462 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301463 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301464 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1465 uint8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301466 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301467 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301468 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301469 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301470 }
1471 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1472 int8_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301473 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301474 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301475 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301476 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301477 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301478 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301479 uint16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301480 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301481 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301482 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301483 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301484 }
1485 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301486 int16_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301487 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301488 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301489 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301490 break;
1491 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301492 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1493 uint32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301494 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301495 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301496 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301497 break;
1498 }
1499 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1500 int32_t val;
Andrew Jeffery66c77232024-04-24 11:42:02 +09301501 if (!pldm_msgbuf_extract(buf, val)) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301502 *present_reading = (uint32_t)val;
1503 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301504 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301505 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301506 default:
1507 return PLDM_ERROR_INVALID_DATA;
1508 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301509
1510 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301511}
1512
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301513LIBPLDM_ABI_STABLE
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301514int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301515 const void *pdr_data, size_t pdr_data_length,
1516 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301517{
1518 struct pldm_msgbuf _buf;
1519 struct pldm_msgbuf *buf = &_buf;
1520 int rc;
1521
Thu Nguyen51230a02023-11-10 16:22:25 +07001522 rc = pldm_msgbuf_init(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301523 pdr_data, pdr_data_length);
1524 if (rc) {
1525 return rc;
1526 }
1527
1528 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1529 if (rc) {
1530 return rc;
1531 }
1532
1533 rc = pldm_platform_pdr_hdr_validate(
Thu Nguyen51230a02023-11-10 16:22:25 +07001534 &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301535 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301536 if (rc) {
1537 return rc;
1538 }
1539
Andrew Jeffery66c77232024-04-24 11:42:02 +09301540 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1541 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1542 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1543 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1544 pldm_msgbuf_extract(buf, pdr_value->container_id);
1545 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1546 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1547 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1548 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1549 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1550 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1551 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1552 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1553 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1554 pldm_msgbuf_extract(buf, pdr_value->rel);
1555 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1556 pldm_msgbuf_extract(buf, pdr_value->is_linear);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301557
Andrew Jeffery66c77232024-04-24 11:42:02 +09301558 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301559 if (rc) {
1560 return rc;
1561 }
1562 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1563 return PLDM_ERROR_INVALID_DATA;
1564 }
1565
Andrew Jeffery66c77232024-04-24 11:42:02 +09301566 pldm_msgbuf_extract(buf, pdr_value->resolution);
1567 pldm_msgbuf_extract(buf, pdr_value->offset);
1568 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1569 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1570 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301571 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1572 &pdr_value->hysteresis);
Andrew Jeffery66c77232024-04-24 11:42:02 +09301573 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301574 pldm_msgbuf_extract(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301575 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1576 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1577 pldm_msgbuf_extract(buf, pdr_value->update_interval);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301578 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1579 &pdr_value->max_readable);
1580 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1581 &pdr_value->min_readable);
1582
Andrew Jeffery66c77232024-04-24 11:42:02 +09301583 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301584 if (rc) {
1585 return rc;
1586 }
1587 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1588 return PLDM_ERROR_INVALID_DATA;
1589 }
1590
Andrew Jeffery66c77232024-04-24 11:42:02 +09301591 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301592 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301593 buf, pdr_value->range_field_format, pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301594 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301595 buf, pdr_value->range_field_format, pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301596 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301597 buf, pdr_value->range_field_format, pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301598 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301599 buf, pdr_value->range_field_format, pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301600 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301601 buf, pdr_value->range_field_format, pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301602 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301603 buf, pdr_value->range_field_format, pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301604 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301605 buf, pdr_value->range_field_format, pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301606 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301607 buf, pdr_value->range_field_format, pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301608 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery66c77232024-04-24 11:42:02 +09301609 buf, pdr_value->range_field_format, pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301610
1611 return pldm_msgbuf_destroy(buf);
1612}
1613
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301614LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301615int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1616 uint16_t effecter_id,
1617 struct pldm_msg *msg)
1618{
1619 if (msg == NULL) {
1620 return PLDM_ERROR_INVALID_DATA;
1621 }
1622
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301623 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301624 header.msg_type = PLDM_REQUEST;
1625 header.instance = instance_id;
1626 header.pldm_type = PLDM_PLATFORM;
1627 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1628
1629 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1630 if (rc != PLDM_SUCCESS) {
1631 return rc;
1632 }
1633
1634 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301635 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301636 request->effecter_id = htole16(effecter_id);
1637
1638 return PLDM_SUCCESS;
1639}
1640
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301641LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301642int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301643 uint8_t instance_id, uint8_t completion_code,
1644 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1645 const uint8_t *pending_value, const uint8_t *present_value,
1646 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301647{
1648 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1649 return PLDM_ERROR_INVALID_DATA;
1650 }
1651
1652 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1653 return PLDM_ERROR_INVALID_DATA;
1654 }
1655
1656 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1657 return PLDM_ERROR_INVALID_DATA;
1658 }
1659
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301660 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301661 header.msg_type = PLDM_RESPONSE;
1662 header.instance = instance_id;
1663 header.pldm_type = PLDM_PLATFORM;
1664 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1665
1666 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1667 if (rc != PLDM_SUCCESS) {
1668 return rc;
1669 }
1670
1671 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301672 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301673
1674 response->completion_code = completion_code;
1675 response->effecter_data_size = effecter_data_size;
1676 response->effecter_oper_state = effecter_oper_state;
1677
1678 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1679 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1680 if (payload_length !=
1681 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1682 return PLDM_ERROR_INVALID_LENGTH;
1683 }
1684 response->pending_and_present_values[0] = *pending_value;
1685 response->pending_and_present_values[1] = *present_value;
1686
1687 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1688 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1689 if (payload_length !=
1690 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1691 return PLDM_ERROR_INVALID_LENGTH;
1692 }
1693 uint16_t val_pending = *(uint16_t *)pending_value;
1694 val_pending = htole16(val_pending);
1695 memcpy(response->pending_and_present_values, &val_pending,
1696 sizeof(uint16_t));
1697 uint16_t val_present = *(uint16_t *)present_value;
1698 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301699 memcpy((response->pending_and_present_values +
1700 sizeof(uint16_t)),
1701 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301702
1703 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1704 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1705 if (payload_length !=
1706 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1707 return PLDM_ERROR_INVALID_LENGTH;
1708 }
1709 uint32_t val_pending = *(uint32_t *)pending_value;
1710 val_pending = htole32(val_pending);
1711 memcpy(response->pending_and_present_values, &val_pending,
1712 sizeof(uint32_t));
1713 uint32_t val_present = *(uint32_t *)present_value;
1714 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301715 memcpy((response->pending_and_present_values +
1716 sizeof(uint32_t)),
1717 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301718 }
1719 return PLDM_SUCCESS;
1720}
1721
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301722LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301723int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1724 size_t payload_length,
1725 uint16_t *effecter_id)
1726{
Andrew Jefferydd265822023-04-13 22:42:44 +09301727 struct pldm_msgbuf _buf;
1728 struct pldm_msgbuf *buf = &_buf;
1729 int rc;
1730
Andrew Jeffery9c766792022-08-10 23:12:49 +09301731 if (msg == NULL || effecter_id == NULL) {
1732 return PLDM_ERROR_INVALID_DATA;
1733 }
1734
Andrew Jefferydd265822023-04-13 22:42:44 +09301735 rc = pldm_msgbuf_init(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
1736 msg->payload, payload_length);
1737 if (rc) {
1738 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301739 }
1740
Andrew Jeffery66c77232024-04-24 11:42:02 +09301741 pldm_msgbuf_extract_p(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301742
Andrew Jefferydd265822023-04-13 22:42:44 +09301743 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301744}
1745
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301746LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301747int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
1748 size_t payload_length,
1749 uint8_t *completion_code,
1750 uint8_t *effecter_data_size,
1751 uint8_t *effecter_oper_state,
1752 uint8_t *pending_value,
1753 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301754{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301755 struct pldm_msgbuf _buf;
1756 struct pldm_msgbuf *buf = &_buf;
1757 int rc;
1758
Andrew Jeffery9c766792022-08-10 23:12:49 +09301759 if (msg == NULL || effecter_data_size == NULL ||
1760 effecter_oper_state == NULL || pending_value == NULL ||
1761 present_value == NULL) {
1762 return PLDM_ERROR_INVALID_DATA;
1763 }
1764
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301765 rc = pldm_msgbuf_init(buf,
1766 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
1767 msg->payload, payload_length);
1768 if (rc) {
1769 return rc;
1770 }
1771
Andrew Jeffery66c77232024-04-24 11:42:02 +09301772 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301773 if (rc) {
1774 return rc;
1775 }
1776
Andrew Jeffery9c766792022-08-10 23:12:49 +09301777 if (PLDM_SUCCESS != *completion_code) {
1778 return PLDM_SUCCESS;
1779 }
1780
Andrew Jeffery66c77232024-04-24 11:42:02 +09301781 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301782 if (rc) {
1783 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301784 }
1785
Andrew Jeffery9c766792022-08-10 23:12:49 +09301786 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1787 return PLDM_ERROR_INVALID_DATA;
1788 }
1789
Andrew Jeffery66c77232024-04-24 11:42:02 +09301790 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301791 if (rc) {
1792 return rc;
1793 }
1794
Andrew Jeffery9c766792022-08-10 23:12:49 +09301795 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1796 return PLDM_ERROR_INVALID_DATA;
1797 }
1798
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301799 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1800 pending_value);
1801 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1802 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301803
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301804 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301805}
1806
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301807LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301808int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301809 uint8_t event_data_format, uint8_t number_of_change_records,
1810 const uint8_t *event_data_operations,
1811 const uint8_t *numbers_of_change_entries,
1812 const uint32_t *const *change_entries,
1813 struct pldm_pdr_repository_chg_event_data *event_data,
1814 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301815{
1816 if (event_data_operations == NULL ||
1817 numbers_of_change_entries == NULL || change_entries == NULL) {
1818 return PLDM_ERROR_INVALID_DATA;
1819 }
1820
1821 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301822 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301823
1824 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301825 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301826 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301827 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301828
1829 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301830 expected_size += sizeof(*change_entries[0]) *
1831 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301832 }
1833
1834 *actual_change_records_size = expected_size;
1835
1836 if (event_data == NULL) {
1837 return PLDM_SUCCESS;
1838 }
1839
1840 if (max_change_records_size < expected_size) {
1841 return PLDM_ERROR_INVALID_LENGTH;
1842 }
1843
1844 event_data->event_data_format = event_data_format;
1845 event_data->number_of_change_records = number_of_change_records;
1846
1847 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301848 (struct pldm_pdr_repository_change_record_data *)
1849 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301850
1851 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1852 record_data->event_data_operation = event_data_operations[i];
1853 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301854 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301855
1856 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1857 ++j) {
1858 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301859 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301860 }
1861
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301862 record_data =
1863 (struct pldm_pdr_repository_change_record_data
1864 *)(record_data->change_entry +
1865 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301866 }
1867
1868 return PLDM_SUCCESS;
1869}
1870
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301871LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301872int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1873 size_t event_data_size,
1874 uint8_t *event_data_format,
1875 uint8_t *number_of_change_records,
1876 size_t *change_record_data_offset)
1877{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301878 struct pldm_msgbuf _buf;
1879 struct pldm_msgbuf *buf = &_buf;
1880 int rc;
1881
1882 if (event_data_format == NULL || number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301883 change_record_data_offset == NULL) {
1884 return PLDM_ERROR_INVALID_DATA;
1885 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301886
1887 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
1888 event_data, event_data_size);
1889 if (rc) {
1890 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301891 }
1892
Andrew Jeffery66c77232024-04-24 11:42:02 +09301893 pldm_msgbuf_extract_p(buf, event_data_format);
1894 pldm_msgbuf_extract_p(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301895
Andrew Jeffery9c766792022-08-10 23:12:49 +09301896 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301897 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301898
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301899 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301900}
1901
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301902LIBPLDM_ABI_TESTING
Dung Cao7c250342022-11-16 22:40:37 +07001903int decode_pldm_message_poll_event_data(const uint8_t *event_data,
1904 size_t event_data_length,
1905 uint8_t *format_version,
1906 uint16_t *event_id,
1907 uint32_t *data_transfer_handle)
1908{
1909 struct pldm_msgbuf _buf;
1910 struct pldm_msgbuf *buf = &_buf;
1911 int rc;
1912
1913 if (event_data == NULL || format_version == NULL || event_id == NULL ||
1914 data_transfer_handle == NULL) {
1915 return PLDM_ERROR_INVALID_DATA;
1916 }
1917
1918 rc = pldm_msgbuf_init(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
1919 event_data_length);
1920 if (rc) {
1921 return rc;
1922 }
1923
Andrew Jeffery66c77232024-04-24 11:42:02 +09301924 pldm_msgbuf_extract_p(buf, format_version);
1925 rc = pldm_msgbuf_extract_p(buf, event_id);
Dung Cao7c250342022-11-16 22:40:37 +07001926 if (rc) {
1927 return rc;
1928 }
1929
1930 if (*event_id == 0x0000 || *event_id == 0xffff) {
1931 return PLDM_ERROR_INVALID_DATA;
1932 }
1933
Andrew Jeffery66c77232024-04-24 11:42:02 +09301934 pldm_msgbuf_extract_p(buf, 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
Dung Cao7c250342022-11-16 22:40:37 +07001940int encode_pldm_message_poll_event_data(uint8_t format_version,
1941 uint16_t event_id,
1942 uint32_t data_transfer_handle,
1943 uint8_t *event_data,
1944 size_t event_data_length)
1945{
1946 struct pldm_msgbuf _buf;
1947 struct pldm_msgbuf *buf = &_buf;
1948 int rc;
1949
1950 if (event_data == NULL) {
1951 return PLDM_ERROR_INVALID_DATA;
1952 }
1953
1954 if (event_id == 0x0000 || event_id == 0xffff) {
1955 return PLDM_ERROR_INVALID_DATA;
1956 }
1957
1958 rc = pldm_msgbuf_init(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
1959 event_data_length);
1960 if (rc) {
1961 return rc;
1962 }
1963 pldm_msgbuf_insert(buf, format_version);
1964 pldm_msgbuf_insert(buf, event_id);
1965 pldm_msgbuf_insert(buf, data_transfer_handle);
1966
1967 return pldm_msgbuf_destroy(buf);
1968}
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09301969
1970LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09301971int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301972 const uint8_t *change_record_data, size_t change_record_data_size,
1973 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1974 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301975{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301976 struct pldm_msgbuf _buf;
1977 struct pldm_msgbuf *buf = &_buf;
1978 int rc;
1979
1980 if (event_data_operation == NULL || number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301981 change_entry_data_offset == NULL) {
1982 return PLDM_ERROR_INVALID_DATA;
1983 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301984
1985 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
1986 change_record_data, change_record_data_size);
1987 if (rc) {
1988 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301989 }
1990
Andrew Jeffery66c77232024-04-24 11:42:02 +09301991 pldm_msgbuf_extract_p(buf, event_data_operation);
1992 pldm_msgbuf_extract_p(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301993
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301994 *change_entry_data_offset = sizeof(*event_data_operation) +
1995 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301996
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301997 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301998}
1999
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302000LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302001int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2002 uint8_t rearm_event_state,
2003 struct pldm_msg *msg)
2004{
2005 if (msg == NULL) {
2006 return PLDM_ERROR_INVALID_DATA;
2007 }
2008
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302009 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302010 header.msg_type = PLDM_REQUEST;
2011 header.instance = instance_id;
2012 header.pldm_type = PLDM_PLATFORM;
2013 header.command = PLDM_GET_SENSOR_READING;
2014
2015 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2016 if (rc != PLDM_SUCCESS) {
2017 return rc;
2018 }
2019
2020 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302021 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302022
2023 request->sensor_id = htole16(sensor_id);
2024 request->rearm_event_state = rearm_event_state;
2025
2026 return PLDM_SUCCESS;
2027}
2028
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302029LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302030int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302031 const struct pldm_msg *msg, size_t payload_length,
2032 uint8_t *completion_code, uint8_t *sensor_data_size,
2033 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2034 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2035 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302036{
Andrew Jeffery840b1402023-04-13 23:54:44 +09302037 struct pldm_msgbuf _buf;
2038 struct pldm_msgbuf *buf = &_buf;
2039 int rc;
2040
Andrew Jeffery9c766792022-08-10 23:12:49 +09302041 if (msg == NULL || completion_code == NULL ||
2042 sensor_data_size == NULL || sensor_operational_state == NULL ||
2043 sensor_event_message_enable == NULL || present_state == NULL ||
2044 previous_state == NULL || event_state == NULL ||
2045 present_reading == NULL) {
2046 return PLDM_ERROR_INVALID_DATA;
2047 }
2048
Andrew Jeffery840b1402023-04-13 23:54:44 +09302049 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2050 msg->payload, payload_length);
2051 if (rc) {
2052 return rc;
2053 }
2054
Andrew Jeffery66c77232024-04-24 11:42:02 +09302055 rc = pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302056 if (rc) {
2057 return rc;
2058 }
2059
Andrew Jeffery9c766792022-08-10 23:12:49 +09302060 if (PLDM_SUCCESS != *completion_code) {
2061 return PLDM_SUCCESS;
2062 }
2063
Andrew Jeffery66c77232024-04-24 11:42:02 +09302064 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
Andrew Jeffery840b1402023-04-13 23:54:44 +09302065 if (rc) {
2066 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302067 }
2068
Andrew Jeffery840b1402023-04-13 23:54:44 +09302069 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09302070 return PLDM_ERROR_INVALID_DATA;
2071 }
2072
Andrew Jeffery66c77232024-04-24 11:42:02 +09302073 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2074 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2075 pldm_msgbuf_extract_p(buf, present_state);
2076 pldm_msgbuf_extract_p(buf, previous_state);
2077 pldm_msgbuf_extract_p(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302078
Andrew Jeffery840b1402023-04-13 23:54:44 +09302079 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2080 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302081
Andrew Jeffery840b1402023-04-13 23:54:44 +09302082 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302083}
2084
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302085LIBPLDM_ABI_STABLE
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302086int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2087 uint8_t sensor_data_size,
2088 uint8_t sensor_operational_state,
2089 uint8_t sensor_event_message_enable,
2090 uint8_t present_state,
2091 uint8_t previous_state, uint8_t event_state,
2092 const uint8_t *present_reading,
2093 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302094{
2095 if (msg == NULL || present_reading == NULL) {
2096 return PLDM_ERROR_INVALID_DATA;
2097 }
2098
2099 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2100 return PLDM_ERROR_INVALID_DATA;
2101 }
2102
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302103 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302104 header.msg_type = PLDM_RESPONSE;
2105 header.instance = instance_id;
2106 header.pldm_type = PLDM_PLATFORM;
2107 header.command = PLDM_GET_SENSOR_READING;
2108
2109 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2110 if (rc != PLDM_SUCCESS) {
2111 return rc;
2112 }
2113
2114 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302115 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302116
2117 response->completion_code = completion_code;
2118 response->sensor_data_size = sensor_data_size;
2119 response->sensor_operational_state = sensor_operational_state;
2120 response->sensor_event_message_enable = sensor_event_message_enable;
2121 response->present_state = present_state;
2122 response->previous_state = previous_state;
2123 response->event_state = event_state;
2124
2125 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2126 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2127 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2128 return PLDM_ERROR_INVALID_LENGTH;
2129 }
2130 response->present_reading[0] = *present_reading;
2131
2132 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2133 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2134 if (payload_length !=
2135 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2136 return PLDM_ERROR_INVALID_LENGTH;
2137 }
2138 uint16_t val = *(uint16_t *)present_reading;
2139 val = htole16(val);
2140 memcpy(response->present_reading, &val, 2);
2141
2142 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2143 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2144 if (payload_length !=
2145 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2146 return PLDM_ERROR_INVALID_LENGTH;
2147 }
2148 uint32_t val = *(uint32_t *)present_reading;
2149 val = htole32(val);
2150 memcpy(response->present_reading, &val, 4);
2151 }
2152
2153 return PLDM_SUCCESS;
2154}
2155
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302156LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302157int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2158 size_t payload_length, uint16_t *sensor_id,
2159 uint8_t *rearm_event_state)
2160{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302161 struct pldm_msgbuf _buf;
2162 struct pldm_msgbuf *buf = &_buf;
2163 int rc;
2164
Andrew Jeffery9c766792022-08-10 23:12:49 +09302165 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2166 return PLDM_ERROR_INVALID_DATA;
2167 }
2168
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302169 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2170 msg->payload, payload_length);
2171 if (rc) {
2172 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302173 }
2174
Andrew Jeffery66c77232024-04-24 11:42:02 +09302175 pldm_msgbuf_extract_p(buf, sensor_id);
2176 pldm_msgbuf_extract_p(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302177
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302178 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302179}
2180
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302181LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302182int encode_set_event_receiver_req(uint8_t instance_id,
2183 uint8_t event_message_global_enable,
2184 uint8_t transport_protocol_type,
2185 uint8_t event_receiver_address_info,
2186 uint16_t heartbeat_timer,
2187 struct pldm_msg *msg)
2188{
2189 if (msg == NULL) {
2190 return PLDM_ERROR_INVALID_DATA;
2191 }
2192
2193 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2194 return PLDM_ERROR_INVALID_DATA;
2195 }
2196
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302197 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302198 header.msg_type = PLDM_REQUEST;
2199 header.instance = instance_id;
2200 header.pldm_type = PLDM_PLATFORM;
2201 header.command = PLDM_SET_EVENT_RECEIVER;
2202
2203 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2204 if (rc != PLDM_SUCCESS) {
2205 return rc;
2206 }
2207
2208 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302209 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302210 request->event_message_global_enable = event_message_global_enable;
2211
2212 request->transport_protocol_type = transport_protocol_type;
2213 request->event_receiver_address_info = event_receiver_address_info;
2214
2215 if (event_message_global_enable ==
2216 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2217 if (heartbeat_timer == 0) {
2218 return PLDM_ERROR_INVALID_DATA;
2219 }
2220 request->heartbeat_timer = htole16(heartbeat_timer);
2221 }
2222
2223 return PLDM_SUCCESS;
2224}
2225
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302226LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302227int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2228 size_t payload_length,
2229 uint8_t *completion_code)
2230{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302231 struct pldm_msgbuf _buf;
2232 struct pldm_msgbuf *buf = &_buf;
2233 int rc;
2234
Andrew Jeffery9c766792022-08-10 23:12:49 +09302235 if (msg == NULL || completion_code == NULL) {
2236 return PLDM_ERROR_INVALID_DATA;
2237 }
2238
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302239 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2240 msg->payload, payload_length);
2241 if (rc) {
2242 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302243 }
2244
Andrew Jeffery66c77232024-04-24 11:42:02 +09302245 pldm_msgbuf_extract_p(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302246
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302247 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302248}
2249
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302250LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302251int decode_set_event_receiver_req(const struct pldm_msg *msg,
2252 size_t payload_length,
2253 uint8_t *event_message_global_enable,
2254 uint8_t *transport_protocol_type,
2255 uint8_t *event_receiver_address_info,
2256 uint16_t *heartbeat_timer)
2257
2258{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302259 struct pldm_msgbuf _buf;
2260 struct pldm_msgbuf *buf = &_buf;
2261 int rc;
2262
Andrew Jeffery9c766792022-08-10 23:12:49 +09302263 if (msg == NULL || event_message_global_enable == NULL ||
2264 transport_protocol_type == NULL ||
2265 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2266 return PLDM_ERROR_INVALID_DATA;
2267 }
2268
Andrew Jeffery9667f582023-04-14 00:39:21 +09302269 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2270 msg->payload, payload_length);
2271 if (rc) {
2272 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302273 }
2274
Andrew Jeffery66c77232024-04-24 11:42:02 +09302275 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2276 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2277 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
2278 pldm_msgbuf_extract_p(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302279
Andrew Jeffery9667f582023-04-14 00:39:21 +09302280 rc = pldm_msgbuf_destroy(buf);
2281 if (rc) {
2282 return rc;
2283 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302284
Andrew Jeffery9c766792022-08-10 23:12:49 +09302285 if ((*event_message_global_enable ==
2286 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2287 (*heartbeat_timer == 0)) {
2288 return PLDM_ERROR_INVALID_DATA;
2289 }
2290
Andrew Jeffery9c766792022-08-10 23:12:49 +09302291 return PLDM_SUCCESS;
2292}
2293
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302294LIBPLDM_ABI_STABLE
Andrew Jeffery9c766792022-08-10 23:12:49 +09302295int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2296 struct pldm_msg *msg)
2297
2298{
2299 if (msg == NULL) {
2300 return PLDM_ERROR_INVALID_DATA;
2301 }
2302
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302303 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302304 header.instance = instance_id;
2305 header.msg_type = PLDM_RESPONSE;
2306 header.pldm_type = PLDM_PLATFORM;
2307 header.command = PLDM_SET_EVENT_RECEIVER;
2308
2309 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2310 if (rc != PLDM_SUCCESS) {
2311 return rc;
2312 }
2313
2314 msg->payload[0] = completion_code;
2315
2316 return PLDM_SUCCESS;
2317}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002318
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302319LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002320int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2321 uint8_t format_version,
2322 uint8_t transfer_operation_flag,
2323 uint32_t data_transfer_handle,
2324 uint16_t event_id_to_acknowledge,
2325 struct pldm_msg *msg,
2326 size_t payload_length)
2327{
2328 struct pldm_msgbuf _buf;
2329 struct pldm_msgbuf *buf = &_buf;
2330 int rc;
2331
2332 if (msg == NULL) {
2333 return PLDM_ERROR_INVALID_DATA;
2334 }
2335
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302336 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002337 header.msg_type = PLDM_REQUEST;
2338 header.instance = instance_id;
2339 header.pldm_type = PLDM_PLATFORM;
2340 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2341
2342 rc = pack_pldm_header(&header, &(msg->hdr));
2343 if (rc != PLDM_SUCCESS) {
2344 return rc;
2345 }
2346
2347 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302348 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2349 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002350 if (rc) {
2351 return rc;
2352 }
2353
2354 pldm_msgbuf_insert(buf, format_version);
2355 pldm_msgbuf_insert(buf, transfer_operation_flag);
2356 pldm_msgbuf_insert(buf, data_transfer_handle);
2357 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2358
2359 return pldm_msgbuf_destroy(buf);
2360}
2361
Andrew Jeffery9d2a1c62023-06-05 13:02:16 +09302362LIBPLDM_ABI_STABLE
Thu Nguyen159a98b2022-11-02 10:00:10 +07002363int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302364 const struct pldm_msg *msg, size_t payload_length,
2365 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2366 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2367 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2368 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002369{
2370 struct pldm_msgbuf _buf;
2371 struct pldm_msgbuf *buf = &_buf;
2372 int rc;
2373
2374 if (msg == NULL || completion_code == NULL || tid == NULL ||
2375 event_id == NULL || next_data_transfer_handle == NULL ||
2376 transfer_flag == NULL || event_class == NULL ||
2377 event_data_size == NULL || event_data == NULL ||
2378 event_data_integrity_checksum == NULL) {
2379 return PLDM_ERROR_INVALID_DATA;
2380 }
2381
2382 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302383 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2384 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002385 if (rc) {
2386 return rc;
2387 }
2388
Andrew Jeffery66c77232024-04-24 11:42:02 +09302389 rc = pldm_msgbuf_extract_p(buf, completion_code);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002390 if (rc) {
2391 return rc;
2392 }
2393 if (PLDM_SUCCESS != *completion_code) {
2394 return *completion_code;
2395 }
2396
Andrew Jeffery66c77232024-04-24 11:42:02 +09302397 pldm_msgbuf_extract_p(buf, tid);
2398 rc = pldm_msgbuf_extract_p(buf, event_id);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002399 if (rc) {
2400 return rc;
2401 }
2402 if ((*event_id == 0) || (*event_id == 0xffff)) {
2403 return PLDM_SUCCESS;
2404 }
2405
Andrew Jeffery66c77232024-04-24 11:42:02 +09302406 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2407 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002408 if (rc) {
2409 return rc;
2410 }
2411
Andrew Jeffery66c77232024-04-24 11:42:02 +09302412 pldm_msgbuf_extract_p(buf, event_class);
2413 rc = pldm_msgbuf_extract_p(buf, event_data_size);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002414 if (rc) {
2415 return rc;
2416 }
2417 if (*event_data_size > payload_length) {
2418 return PLDM_ERROR_INVALID_DATA;
2419 }
2420
2421 if (*event_data_size > 0) {
2422 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2423 }
2424
2425 if (*transfer_flag == PLDM_END ||
2426 *transfer_flag == PLDM_START_AND_END) {
Andrew Jeffery66c77232024-04-24 11:42:02 +09302427 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002428 }
2429
2430 return pldm_msgbuf_destroy_consumed(buf);
2431}
Thu Nguyend4878cd2023-11-09 10:18:33 +07002432
2433LIBPLDM_ABI_TESTING
2434int decode_numeric_effecter_pdr_data(
2435 const void *pdr_data, size_t pdr_data_length,
2436 struct pldm_numeric_effecter_value_pdr *pdr_value)
2437{
2438 struct pldm_msgbuf _buf;
2439 struct pldm_msgbuf *buf = &_buf;
2440 struct pldm_value_pdr_hdr hdr;
2441 int rc;
2442
2443 rc = pldm_msgbuf_init(buf, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2444 pdr_data, pdr_data_length);
2445 if (rc) {
2446 return rc;
2447 }
2448
2449 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &hdr);
2450 if (rc) {
2451 return rc;
2452 }
2453
2454 rc = pldm_platform_pdr_hdr_validate(
2455 &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2456 pdr_data_length);
2457 if (rc) {
2458 return rc;
2459 }
2460
2461 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2462
2463 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2464 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2465 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2466 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2467 pldm_msgbuf_extract(buf, pdr_value->container_id);
2468 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2469 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2470 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2471 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2472 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2473 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2474 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2475 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2476 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2477 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2478 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2479 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2480
2481 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2482 if (rc) {
2483 return rc;
2484 }
2485 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2486 return PLDM_ERROR_INVALID_DATA;
2487 }
2488
2489 pldm_msgbuf_extract(buf, pdr_value->resolution);
2490 pldm_msgbuf_extract(buf, pdr_value->offset);
2491 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2492 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2493 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2494 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2495 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2496 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2497 pdr_value->max_settable);
2498 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2499 pdr_value->min_settable);
2500
2501 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2502 if (rc) {
2503 return rc;
2504 }
2505 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2506 return PLDM_ERROR_INVALID_DATA;
2507 }
2508
2509 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2510 pldm_msgbuf_extract_range_field_format(
2511 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2512 pldm_msgbuf_extract_range_field_format(
2513 buf, pdr_value->range_field_format, pdr_value->normal_max);
2514 pldm_msgbuf_extract_range_field_format(
2515 buf, pdr_value->range_field_format, pdr_value->normal_min);
2516 pldm_msgbuf_extract_range_field_format(
2517 buf, pdr_value->range_field_format, pdr_value->rated_max);
2518 pldm_msgbuf_extract_range_field_format(
2519 buf, pdr_value->range_field_format, pdr_value->rated_min);
2520
2521 return pldm_msgbuf_destroy_consumed(buf);
2522}