blob: 5da538cfa36ebda5098bddb0ae8f7b9a042d20aa [file] [log] [blame]
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301#include "msgbuf/platform.h"
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05302#include "base.h"
Andrew Jeffery7992eb82023-04-06 16:13:53 +09303#include "msgbuf.h"
4#include "platform.h"
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05305#include "pldm_types.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +09306#include <endian.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05307#include <stdint.h>
Thu Nguyen159a98b2022-11-02 10:00:10 +07008#include <stdlib.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <string.h>
10
Andrew Jeffery7992eb82023-04-06 16:13:53 +093011static int pldm_platform_pdr_hdr_validate(struct pldm_value_pdr_hdr *ctx,
12 size_t lower, size_t upper)
13{
14 if (ctx->length + sizeof(*ctx) < lower) {
15 return PLDM_ERROR_INVALID_LENGTH;
16 }
17
18 if (ctx->length > upper) {
19 return PLDM_ERROR_INVALID_LENGTH;
20 }
21
22 return PLDM_SUCCESS;
23}
Andrew Jeffery9c766792022-08-10 23:12:49 +093024
25int encode_state_effecter_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093026 struct pldm_state_effecter_pdr *const effecter,
27 const size_t allocation_size,
28 const struct state_effecter_possible_states *const possible_states,
29 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +093030{
31 // Encode possible states
32
33 size_t calculated_possible_states_size = 0;
34
35 {
36 char *states_ptr = (char *)possible_states;
37 char *const begin_states_ptr = states_ptr;
38
39 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
40 struct state_effecter_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093041 (struct state_effecter_possible_states *)
42 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +093043
44 HTOLE16(states->state_set_id);
45
46 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093047 (sizeof(*states) - sizeof(states->states) +
48 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +093049 }
50
51 calculated_possible_states_size = states_ptr - begin_states_ptr;
52 }
53
54 // Check lengths
55
56 if (possible_states_size != calculated_possible_states_size) {
57 *actual_size = 0;
58 return PLDM_ERROR;
59 }
60
61 *actual_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093062 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
63 sizeof(effecter->possible_states));
Andrew Jeffery9c766792022-08-10 23:12:49 +093064
65 if (allocation_size < *actual_size) {
66 *actual_size = 0;
67 return PLDM_ERROR_INVALID_LENGTH;
68 }
69
70 // Encode rest of PDR
71
72 effecter->hdr.version = 1;
73 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
74 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
75
76 memcpy(effecter->possible_states, possible_states,
77 possible_states_size);
78
79 // Convert effecter PDR body
80 HTOLE16(effecter->terminus_handle);
81 HTOLE16(effecter->effecter_id);
82 HTOLE16(effecter->entity_type);
83 HTOLE16(effecter->entity_instance);
84 HTOLE16(effecter->container_id);
85 HTOLE16(effecter->effecter_semantic_id);
86
87 // Convert header
88 HTOLE32(effecter->hdr.record_handle);
89 HTOLE16(effecter->hdr.record_change_num);
90 HTOLE16(effecter->hdr.length);
91
92 return PLDM_SUCCESS;
93}
94
95int encode_state_sensor_pdr(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093096 struct pldm_state_sensor_pdr *const sensor,
97 const size_t allocation_size,
98 const struct state_sensor_possible_states *const possible_states,
99 const size_t possible_states_size, size_t *const actual_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930100{
101 // Encode possible states
102
103 size_t calculated_possible_states_size = 0;
104
105 {
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930106 char *states_ptr = (char *)possible_states;
107 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930108
109 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
110 struct state_sensor_possible_states *states =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930111 (struct state_sensor_possible_states *)
112 states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930113
114 HTOLE16(states->state_set_id);
115
116 states_ptr +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930117 (sizeof(*states) - sizeof(states->states) +
118 states->possible_states_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930119 }
120
121 calculated_possible_states_size = states_ptr - begin_states_ptr;
122 }
123
124 // Check lengths
125
126 if (possible_states_size != calculated_possible_states_size) {
127 *actual_size = 0;
128 return PLDM_ERROR;
129 }
130
131 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
132 possible_states_size - sizeof(sensor->possible_states));
133
134 if (allocation_size < *actual_size) {
135 *actual_size = 0;
136 return PLDM_ERROR_INVALID_LENGTH;
137 }
138
139 // Encode rest of PDR
140
141 sensor->hdr.version = 1;
142 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
143 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
144
145 memcpy(sensor->possible_states, possible_states, possible_states_size);
146
147 // Convert sensor PDR body
148 HTOLE16(sensor->terminus_handle);
149 HTOLE16(sensor->sensor_id);
150 HTOLE16(sensor->entity_type);
151 HTOLE16(sensor->entity_instance);
152 HTOLE16(sensor->container_id);
153
154 // Convert header
155 HTOLE32(sensor->hdr.record_handle);
156 HTOLE16(sensor->hdr.record_change_num);
157 HTOLE16(sensor->hdr.length);
158
159 return PLDM_SUCCESS;
160}
161
162int encode_set_state_effecter_states_resp(uint8_t instance_id,
163 uint8_t completion_code,
164 struct pldm_msg *msg)
165{
166 if (msg == NULL) {
167 return PLDM_ERROR_INVALID_DATA;
168 }
169
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930170 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930171 header.msg_type = PLDM_RESPONSE;
172 header.instance = instance_id;
173 header.pldm_type = PLDM_PLATFORM;
174 header.command = PLDM_SET_STATE_EFFECTER_STATES;
175
176 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
177 if (rc != PLDM_SUCCESS) {
178 return rc;
179 }
180
181 msg->payload[0] = completion_code;
182
183 return PLDM_SUCCESS;
184}
185
186int encode_set_state_effecter_states_req(uint8_t instance_id,
187 uint16_t effecter_id,
188 uint8_t comp_effecter_count,
189 set_effecter_state_field *field,
190 struct pldm_msg *msg)
191{
192 if (msg == NULL) {
193 return PLDM_ERROR_INVALID_DATA;
194 }
195
196 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
197 field == NULL) {
198 return PLDM_ERROR_INVALID_DATA;
199 }
200
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930201 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930202 header.msg_type = PLDM_REQUEST;
203 header.instance = instance_id;
204 header.pldm_type = PLDM_PLATFORM;
205 header.command = PLDM_SET_STATE_EFFECTER_STATES;
206
207 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
208 if (rc != PLDM_SUCCESS) {
209 return rc;
210 }
211
212 struct pldm_set_state_effecter_states_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930213 (struct pldm_set_state_effecter_states_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930214 effecter_id = htole16(effecter_id);
215 request->effecter_id = effecter_id;
216 request->comp_effecter_count = comp_effecter_count;
217 memcpy(request->field, field,
218 (sizeof(set_effecter_state_field) * comp_effecter_count));
219
220 return PLDM_SUCCESS;
221}
222
223int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
224 size_t payload_length,
225 uint8_t *completion_code)
226{
227 if (msg == NULL || completion_code == NULL) {
228 return PLDM_ERROR_INVALID_DATA;
229 }
230
231 *completion_code = msg->payload[0];
232 if (PLDM_SUCCESS != *completion_code) {
233 return PLDM_SUCCESS;
234 }
235
236 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
237 return PLDM_ERROR_INVALID_LENGTH;
238 }
239
240 return PLDM_SUCCESS;
241}
242
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930243#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9c766792022-08-10 23:12:49 +0930244int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
245 size_t payload_length,
246 uint16_t *effecter_id,
247 uint8_t *comp_effecter_count,
248 set_effecter_state_field *field)
249{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930250 struct pldm_msgbuf _buf;
251 struct pldm_msgbuf *buf = &_buf;
252 int rc;
253 int i;
254
Andrew Jeffery9c766792022-08-10 23:12:49 +0930255 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
256 field == NULL) {
257 return PLDM_ERROR_INVALID_DATA;
258 }
259
260 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
261 return PLDM_ERROR_INVALID_LENGTH;
262 }
263
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930264 rc = pldm_msgbuf_init(buf, PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
265 msg->payload, payload_length);
266 if (rc) {
267 return rc;
268 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930269
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930270 pldm_msgbuf_extract(buf, effecter_id);
271 pldm_msgbuf_extract(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930272
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930273 if (*comp_effecter_count > 8) {
274 return PLDM_ERROR_INVALID_DATA;
275 }
276
277 for (i = 0; i < *comp_effecter_count; i++) {
278 pldm_msgbuf_extract(buf, &field[i].set_request);
279 pldm_msgbuf_extract(buf, &field[i].effecter_state);
280 }
281
282 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930283}
284
285int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
286 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
287 uint8_t *transfer_op_flag, uint16_t *request_cnt,
288 uint16_t *record_chg_num)
289{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930290 struct pldm_msgbuf _buf;
291 struct pldm_msgbuf *buf = &_buf;
292 int rc;
293
Andrew Jeffery9c766792022-08-10 23:12:49 +0930294 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
295 transfer_op_flag == NULL || request_cnt == NULL ||
296 record_chg_num == NULL) {
297 return PLDM_ERROR_INVALID_DATA;
298 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930299
Andrew Jeffery9c766792022-08-10 23:12:49 +0930300 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
301 return PLDM_ERROR_INVALID_LENGTH;
302 }
303
Andrew Jeffery891781e2023-04-04 11:04:18 +0930304 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
305 payload_length);
306 if (rc) {
307 return rc;
308 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930309
Andrew Jeffery891781e2023-04-04 11:04:18 +0930310 pldm_msgbuf_extract(buf, record_hndl);
311 pldm_msgbuf_extract(buf, data_transfer_hndl);
312 pldm_msgbuf_extract(buf, transfer_op_flag);
313 pldm_msgbuf_extract(buf, request_cnt);
314 pldm_msgbuf_extract(buf, record_chg_num);
315
316 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930317}
318
319int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
320 uint32_t next_record_hndl,
321 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
322 uint16_t resp_cnt, const uint8_t *record_data,
323 uint8_t transfer_crc, struct pldm_msg *msg)
324{
325 if (msg == NULL) {
326 return PLDM_ERROR_INVALID_DATA;
327 }
328
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930329 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930330 header.msg_type = PLDM_RESPONSE;
331 header.instance = instance_id;
332 header.pldm_type = PLDM_PLATFORM;
333 header.command = PLDM_GET_PDR;
334
335 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
336 if (rc != PLDM_SUCCESS) {
337 return rc;
338 }
339
340 struct pldm_get_pdr_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930341 (struct pldm_get_pdr_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930342 response->completion_code = completion_code;
343
344 if (response->completion_code == PLDM_SUCCESS) {
345 response->next_record_handle = htole32(next_record_hndl);
346 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930347 htole32(next_data_transfer_hndl);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930348 response->transfer_flag = transfer_flag;
349 response->response_count = htole16(resp_cnt);
350 if (record_data != NULL && resp_cnt > 0) {
351 memcpy(response->record_data, record_data, resp_cnt);
352 }
353 if (transfer_flag == PLDM_END) {
354 uint8_t *dst = msg->payload;
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930355 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
356 resp_cnt;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930357 *dst = transfer_crc;
358 }
359 }
360
361 return PLDM_SUCCESS;
362}
363
364int encode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930365 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
366 const uint8_t *update_time, const uint8_t *oem_update_time,
367 uint32_t record_count, uint32_t repository_size,
368 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
369 struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930370{
371 if (msg == NULL) {
372 return PLDM_ERROR_INVALID_DATA;
373 }
374
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930375 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930376 header.msg_type = PLDM_RESPONSE;
377 header.instance = instance_id;
378 header.pldm_type = PLDM_PLATFORM;
379 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
380
381 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
382 if (rc != PLDM_SUCCESS) {
383 return rc;
384 }
385
386 struct pldm_pdr_repository_info_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930387 (struct pldm_pdr_repository_info_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930388 response->completion_code = completion_code;
389
390 if (response->completion_code == PLDM_SUCCESS) {
391 response->repository_state = repository_state;
392 if (update_time != NULL) {
393 memcpy(response->update_time, update_time,
394 PLDM_TIMESTAMP104_SIZE);
395 }
396 if (oem_update_time != NULL) {
397 memcpy(response->oem_update_time, oem_update_time,
398 PLDM_TIMESTAMP104_SIZE);
399 }
400 response->record_count = htole32(record_count);
401 response->repository_size = htole32(repository_size);
402 response->largest_record_size = htole32(largest_record_size);
403 response->data_transfer_handle_timeout =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930404 data_transfer_handle_timeout;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930405 }
406
407 return PLDM_SUCCESS;
408}
409
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800410int decode_get_pdr_repository_info_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930411 const struct pldm_msg *msg, size_t payload_length,
412 uint8_t *completion_code, uint8_t *repository_state,
413 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
414 uint32_t *repository_size, uint32_t *largest_record_size,
415 uint8_t *data_transfer_handle_timeout)
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800416{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930417 struct pldm_msgbuf _buf;
418 struct pldm_msgbuf *buf = &_buf;
419 int rc;
420
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800421 if (msg == NULL || completion_code == NULL ||
422 repository_state == NULL || update_time == NULL ||
423 oem_update_time == NULL || record_count == NULL ||
424 repository_size == NULL || largest_record_size == NULL ||
425 data_transfer_handle_timeout == NULL) {
426 return PLDM_ERROR_INVALID_DATA;
427 }
428
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930429 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
430 msg->payload, payload_length);
431 if (rc) {
432 return rc;
433 }
434
435 pldm_msgbuf_extract(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800436 if (PLDM_SUCCESS != *completion_code) {
437 return PLDM_SUCCESS;
438 }
439
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930440 pldm_msgbuf_extract(buf, repository_state);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800441 if (*repository_state > PLDM_FAILED) {
442 return PLDM_ERROR_INVALID_DATA;
443 }
444
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930445 pldm_msgbuf_extract_array(buf, update_time, PLDM_TIMESTAMP104_SIZE);
446 pldm_msgbuf_extract_array(buf, oem_update_time, PLDM_TIMESTAMP104_SIZE);
447 pldm_msgbuf_extract(buf, record_count);
448 pldm_msgbuf_extract(buf, repository_size);
449 pldm_msgbuf_extract(buf, largest_record_size);
450 pldm_msgbuf_extract(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800451
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930452 return pldm_msgbuf_destroy(buf);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800453}
454
Andrew Jeffery9c766792022-08-10 23:12:49 +0930455int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
456 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
457 uint16_t request_cnt, uint16_t record_chg_num,
458 struct pldm_msg *msg, size_t payload_length)
459{
460 if (msg == NULL) {
461 return PLDM_ERROR_INVALID_DATA;
462 }
463
464 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
465 return PLDM_ERROR_INVALID_LENGTH;
466 }
467
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930468 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930469 header.msg_type = PLDM_REQUEST;
470 header.instance = instance_id;
471 header.pldm_type = PLDM_PLATFORM;
472 header.command = PLDM_GET_PDR;
473
474 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
475 if (rc != PLDM_SUCCESS) {
476 return rc;
477 }
478
479 struct pldm_get_pdr_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930480 (struct pldm_get_pdr_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930481 request->record_handle = htole32(record_hndl);
482 request->data_transfer_handle = htole32(data_transfer_hndl);
483 request->transfer_op_flag = transfer_op_flag;
484 request->request_count = htole16(request_cnt);
485 request->record_change_number = htole16(record_chg_num);
486
487 return PLDM_SUCCESS;
488}
489
490int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
491 uint8_t *completion_code, uint32_t *next_record_hndl,
492 uint32_t *next_data_transfer_hndl,
493 uint8_t *transfer_flag, uint16_t *resp_cnt,
494 uint8_t *record_data, size_t record_data_length,
495 uint8_t *transfer_crc)
496{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930497 struct pldm_msgbuf _buf;
498 struct pldm_msgbuf *buf = &_buf;
499 int rc;
500
Andrew Jeffery9c766792022-08-10 23:12:49 +0930501 if (msg == NULL || completion_code == NULL ||
502 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
503 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
504 return PLDM_ERROR_INVALID_DATA;
505 }
506
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930507 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
508 payload_length);
509 if (rc) {
510 return rc;
511 }
512
513 pldm_msgbuf_extract(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930514 if (PLDM_SUCCESS != *completion_code) {
515 return PLDM_SUCCESS;
516 }
517
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930518 pldm_msgbuf_extract(buf, next_record_hndl);
519 pldm_msgbuf_extract(buf, next_data_transfer_hndl);
520 pldm_msgbuf_extract(buf, transfer_flag);
521 rc = pldm_msgbuf_extract(buf, resp_cnt);
522 if (rc) {
523 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930524 }
525
526 if (*resp_cnt > 0 && record_data != NULL) {
527 if (record_data_length < *resp_cnt) {
528 return PLDM_ERROR_INVALID_LENGTH;
529 }
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930530 pldm_msgbuf_extract_array(buf, record_data, *resp_cnt);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930531 }
532
533 if (*transfer_flag == PLDM_END) {
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930534 pldm_msgbuf_extract(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930535 }
536
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930537 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930538}
539
540int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
541 size_t payload_length,
542 uint16_t *effecter_id,
543 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930544 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930545{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930546 struct pldm_msgbuf _buf;
547 struct pldm_msgbuf *buf = &_buf;
548 int rc;
549
Andrew Jeffery9c766792022-08-10 23:12:49 +0930550 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
551 effecter_value == NULL) {
552 return PLDM_ERROR_INVALID_DATA;
553 }
554
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930555 rc = pldm_msgbuf_init(buf,
556 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
557 msg->payload, payload_length);
Andrew Jeffery3884c442023-04-12 11:13:24 +0930558 if (rc) {
559 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930560 }
561
Andrew Jeffery3884c442023-04-12 11:13:24 +0930562 pldm_msgbuf_extract(buf, effecter_id);
563 rc = pldm_msgbuf_extract(buf, effecter_data_size);
564 if (rc) {
565 return PLDM_ERROR_INVALID_DATA;
566 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930567
568 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
569 return PLDM_ERROR_INVALID_DATA;
570 }
571
Andrew Jeffery3884c442023-04-12 11:13:24 +0930572 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
573 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930574
Andrew Jeffery3884c442023-04-12 11:13:24 +0930575 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930576}
577
578int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
579 uint8_t completion_code,
580 struct pldm_msg *msg,
581 size_t payload_length)
582{
583 if (msg == NULL) {
584 return PLDM_ERROR_INVALID_DATA;
585 }
586
587 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
588 return PLDM_ERROR_INVALID_LENGTH;
589 }
590
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930591 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930592 header.msg_type = PLDM_RESPONSE;
593 header.instance = instance_id;
594 header.pldm_type = PLDM_PLATFORM;
595 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
596
597 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
598 if (rc != PLDM_SUCCESS) {
599 return rc;
600 }
601
602 msg->payload[0] = completion_code;
603
604 return rc;
605}
606
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930607int encode_set_numeric_effecter_value_req(uint8_t instance_id,
608 uint16_t effecter_id,
609 uint8_t effecter_data_size,
610 const uint8_t *effecter_value,
611 struct pldm_msg *msg,
612 size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930613{
614 if (msg == NULL || effecter_value == NULL) {
615 return PLDM_ERROR_INVALID_DATA;
616 }
617
618 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
619 return PLDM_ERROR_INVALID_DATA;
620 }
621
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930622 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930623 header.msg_type = PLDM_REQUEST;
624 header.instance = instance_id;
625 header.pldm_type = PLDM_PLATFORM;
626 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
627
628 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
629 if (rc != PLDM_SUCCESS) {
630 return rc;
631 }
632
633 struct pldm_set_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930634 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930635 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
636 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
637 if (payload_length !=
638 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
639 return PLDM_ERROR_INVALID_LENGTH;
640 }
641 request->effecter_value[0] = *effecter_value;
642 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
643 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
644 if (payload_length !=
645 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
646 return PLDM_ERROR_INVALID_LENGTH;
647 }
648
649 uint16_t val = *(uint16_t *)(effecter_value);
650 val = htole16(val);
651 memcpy(request->effecter_value, &val, sizeof(uint16_t));
652
653 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
654 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
655 if (payload_length !=
656 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
657 return PLDM_ERROR_INVALID_LENGTH;
658 }
659
660 uint32_t val = *(uint32_t *)(effecter_value);
661 val = htole32(val);
662 memcpy(request->effecter_value, &val, sizeof(uint32_t));
663 }
664
665 request->effecter_id = htole16(effecter_id);
666 request->effecter_data_size = effecter_data_size;
667
668 return PLDM_SUCCESS;
669}
670
671int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
672 size_t payload_length,
673 uint8_t *completion_code)
674{
675 if (msg == NULL || completion_code == NULL) {
676 return PLDM_ERROR_INVALID_DATA;
677 }
678
679 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
680 return PLDM_ERROR_INVALID_LENGTH;
681 }
682
683 *completion_code = msg->payload[0];
684
685 return PLDM_SUCCESS;
686}
687
688int encode_get_state_sensor_readings_resp(uint8_t instance_id,
689 uint8_t completion_code,
690 uint8_t comp_sensor_count,
691 get_sensor_state_field *field,
692 struct pldm_msg *msg)
693{
694 if (msg == NULL) {
695 return PLDM_ERROR_INVALID_DATA;
696 }
697
698 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
699 return PLDM_ERROR_INVALID_DATA;
700 }
701
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930702 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930703 header.msg_type = PLDM_RESPONSE;
704 header.instance = instance_id;
705 header.pldm_type = PLDM_PLATFORM;
706 header.command = PLDM_GET_STATE_SENSOR_READINGS;
707
708 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
709 if (rc != PLDM_SUCCESS) {
710 return rc;
711 }
712
713 struct pldm_get_state_sensor_readings_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930714 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930715
716 response->completion_code = completion_code;
717 response->comp_sensor_count = comp_sensor_count;
718 memcpy(response->field, field,
719 (sizeof(get_sensor_state_field) * comp_sensor_count));
720
721 return PLDM_SUCCESS;
722}
723
724int encode_get_state_sensor_readings_req(uint8_t instance_id,
725 uint16_t sensor_id,
726 bitfield8_t sensor_rearm,
727 uint8_t reserved, struct pldm_msg *msg)
728{
729 if (msg == NULL) {
730 return PLDM_ERROR_INVALID_DATA;
731 }
732
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930733 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930734 header.msg_type = PLDM_REQUEST;
735 header.instance = instance_id;
736 header.pldm_type = PLDM_PLATFORM;
737 header.command = PLDM_GET_STATE_SENSOR_READINGS;
738
739 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
740 if (rc != PLDM_SUCCESS) {
741 return rc;
742 }
743
744 struct pldm_get_state_sensor_readings_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930745 (struct pldm_get_state_sensor_readings_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930746
747 request->sensor_id = htole16(sensor_id);
748 request->reserved = reserved;
749 request->sensor_rearm = sensor_rearm;
750
751 return PLDM_SUCCESS;
752}
753
754int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
755 size_t payload_length,
756 uint8_t *completion_code,
757 uint8_t *comp_sensor_count,
758 get_sensor_state_field *field)
759{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930760 struct pldm_msgbuf _buf;
761 struct pldm_msgbuf *buf = &_buf;
762 uint8_t i;
763 int rc;
764
Andrew Jeffery9c766792022-08-10 23:12:49 +0930765 if (msg == NULL || completion_code == NULL ||
766 comp_sensor_count == NULL || field == NULL) {
767 return PLDM_ERROR_INVALID_DATA;
768 }
769
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930770 rc = pldm_msgbuf_init(buf,
771 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
772 msg->payload, payload_length);
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930773 if (rc) {
774 return rc;
775 }
776
777 rc = pldm_msgbuf_extract(buf, completion_code);
778 if (rc) {
779 return rc;
780 }
781
Andrew Jeffery9c766792022-08-10 23:12:49 +0930782 if (PLDM_SUCCESS != *completion_code) {
783 return PLDM_SUCCESS;
784 }
785
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930786 rc = pldm_msgbuf_extract(buf, comp_sensor_count);
787 if (rc) {
788 return rc;
789 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930790
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930791 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930792 return PLDM_ERROR_INVALID_DATA;
793 }
794
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930795 for (i = 0; i < *comp_sensor_count; i++) {
796 pldm_msgbuf_extract(buf, &field[i].sensor_op_state);
797 pldm_msgbuf_extract(buf, &field[i].present_state);
798 pldm_msgbuf_extract(buf, &field[i].previous_state);
799 pldm_msgbuf_extract(buf, &field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930800 }
801
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930802 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930803}
804
805int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
806 size_t payload_length,
807 uint16_t *sensor_id,
808 bitfield8_t *sensor_rearm,
809 uint8_t *reserved)
810{
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930811 struct pldm_msgbuf _buf;
812 struct pldm_msgbuf *buf = &_buf;
813 int rc;
814
Andrew Jeffery9c766792022-08-10 23:12:49 +0930815 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
816 return PLDM_ERROR_INVALID_DATA;
817 }
818
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930819 rc = pldm_msgbuf_init(buf, PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
820 msg->payload, payload_length);
821 if (rc) {
822 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930823 }
824
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930825 pldm_msgbuf_extract(buf, sensor_id);
826 pldm_msgbuf_extract(buf, &sensor_rearm->byte);
827 pldm_msgbuf_extract(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930828
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930829 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930830}
831
832int encode_sensor_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930833 struct pldm_sensor_event_data *const event_data,
834 const size_t event_data_size, const uint16_t sensor_id,
835 const enum sensor_event_class_states sensor_event_class,
836 const uint8_t sensor_offset, const uint8_t event_state,
837 const uint8_t previous_event_state,
838 size_t *const actual_event_data_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930839{
840 *actual_event_data_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930841 (sizeof(*event_data) - sizeof(event_data->event_class) +
842 sizeof(struct pldm_sensor_event_state_sensor_state));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930843
844 if (!event_data) {
845 return PLDM_SUCCESS;
846 }
847
848 if (event_data_size < *actual_event_data_size) {
849 *actual_event_data_size = 0;
850 return PLDM_ERROR_INVALID_LENGTH;
851 }
852
853 event_data->sensor_id = htole16(sensor_id);
854 event_data->sensor_event_class_type = sensor_event_class;
855
856 struct pldm_sensor_event_state_sensor_state *const state_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930857 (struct pldm_sensor_event_state_sensor_state *)
858 event_data->event_class;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930859
860 state_data->sensor_offset = sensor_offset;
861 state_data->event_state = event_state;
862 state_data->previous_event_state = previous_event_state;
863
864 return PLDM_SUCCESS;
865}
866
867int decode_platform_event_message_req(const struct pldm_msg *msg,
868 size_t payload_length,
869 uint8_t *format_version, uint8_t *tid,
870 uint8_t *event_class,
871 size_t *event_data_offset)
872{
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930873 struct pldm_msgbuf _buf;
874 struct pldm_msgbuf *buf = &_buf;
875 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930876
877 if (msg == NULL || format_version == NULL || tid == NULL ||
878 event_class == NULL || event_data_offset == NULL) {
879 return PLDM_ERROR_INVALID_DATA;
880 }
881
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930882 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
883 msg->payload, payload_length);
884 if (rc) {
885 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930886 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930887
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930888 pldm_msgbuf_extract(buf, format_version);
889 pldm_msgbuf_extract(buf, tid);
890 pldm_msgbuf_extract(buf, event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930891 *event_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930892 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930893
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930894 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930895}
896
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700897int decode_poll_for_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930898 const struct pldm_msg *msg, size_t payload_length,
899 uint8_t *format_version, uint8_t *transfer_operation_flag,
900 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700901{
902 struct pldm_msgbuf _buf;
903 struct pldm_msgbuf *buf = &_buf;
904 int rc;
905
906 if (msg == NULL) {
907 return PLDM_ERROR_INVALID_DATA;
908 }
909
910 rc = pldm_msgbuf_init(buf,
911 PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
912 msg->payload, payload_length);
913 if (rc) {
914 return rc;
915 }
916
917 pldm_msgbuf_extract(buf, format_version);
918 rc = pldm_msgbuf_extract(buf, transfer_operation_flag);
919 if (rc) {
920 return rc;
921 }
922 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
923 return PLDM_ERROR_INVALID_DATA;
924 }
925
926 pldm_msgbuf_extract(buf, data_transfer_handle);
927 rc = pldm_msgbuf_extract(buf, event_id_to_acknowledge);
928 if (rc) {
929 return rc;
930 }
931
932 if (!(((*transfer_operation_flag == PLDM_GET_NEXTPART) &&
933 (*event_id_to_acknowledge == 0xFFFF)) ||
934 ((*transfer_operation_flag == PLDM_GET_FIRSTPART) &&
935 (*event_id_to_acknowledge == 0x000)) ||
936 (*transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY))) {
937 return PLDM_ERROR_INVALID_DATA;
938 }
939
940 return pldm_msgbuf_destroy(buf);
941}
942
Andrew Jeffery9c766792022-08-10 23:12:49 +0930943int encode_platform_event_message_resp(uint8_t instance_id,
944 uint8_t completion_code,
945 uint8_t platform_event_status,
946 struct pldm_msg *msg)
947{
948 if (msg == NULL) {
949 return PLDM_ERROR_INVALID_DATA;
950 }
951
952 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
953 return PLDM_ERROR_INVALID_DATA;
954 }
955
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930956 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930957 header.msg_type = PLDM_RESPONSE;
958 header.instance = instance_id;
959 header.pldm_type = PLDM_PLATFORM;
960 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
961
962 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
963 if (rc != PLDM_SUCCESS) {
964 return rc;
965 }
966
967 struct pldm_platform_event_message_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930968 (struct pldm_platform_event_message_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930969 response->completion_code = completion_code;
970 response->platform_event_status = platform_event_status;
971
972 return PLDM_SUCCESS;
973}
974
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700975int encode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930976 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
977 uint16_t event_id, uint32_t next_data_transfer_handle,
978 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
979 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
980 size_t payload_length)
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700981{
982 struct pldm_msgbuf _buf;
983 struct pldm_msgbuf *buf = &_buf;
984 int rc;
985
986 if (!msg) {
987 return PLDM_ERROR_INVALID_DATA;
988 }
989
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930990 struct pldm_header_info header = { 0 };
Thu Nguyen8eb20f22022-11-16 22:34:55 +0700991 header.msg_type = PLDM_RESPONSE;
992 header.instance = instance_id;
993 header.pldm_type = PLDM_PLATFORM;
994 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
995
996 rc = pack_pldm_header(&header, &(msg->hdr));
997 if (rc != PLDM_SUCCESS) {
998 return rc;
999 }
1000
1001 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301002 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1003 msg->payload, payload_length);
Thu Nguyen8eb20f22022-11-16 22:34:55 +07001004 if (rc) {
1005 return rc;
1006 }
1007
1008 pldm_msgbuf_insert(buf, completion_code);
1009 pldm_msgbuf_insert(buf, tid);
1010 pldm_msgbuf_insert(buf, event_id);
1011
1012 if (event_id == 0xffff || event_id == 0x0000) {
1013 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1014 payload_length) {
1015 return PLDM_ERROR_INVALID_LENGTH;
1016 }
1017 return pldm_msgbuf_destroy(buf);
1018 }
1019
1020 if ((event_data == NULL) && (event_data_size > 0)) {
1021 return PLDM_ERROR_INVALID_DATA;
1022 }
1023
1024 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1025 pldm_msgbuf_insert(buf, transfer_flag);
1026 pldm_msgbuf_insert(buf, event_class);
1027 pldm_msgbuf_insert(buf, event_data_size);
1028
1029 if ((event_data_size > 0) && event_data) {
1030 pldm_msgbuf_insert_array(buf, event_data, event_data_size);
1031 }
1032
1033 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1034 pldm_msgbuf_insert(buf, checksum);
1035 }
1036
1037 return pldm_msgbuf_destroy(buf);
1038}
1039
Andrew Jeffery9c766792022-08-10 23:12:49 +09301040int encode_platform_event_message_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301041 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1042 uint8_t event_class, const uint8_t *event_data,
1043 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301044
1045{
1046 if (format_version != 1) {
1047 return PLDM_ERROR_INVALID_DATA;
1048 }
1049
1050 if (msg == NULL || event_data == NULL) {
1051 return PLDM_ERROR_INVALID_DATA;
1052 }
1053
1054 if (event_data_length == 0) {
1055 return PLDM_ERROR_INVALID_DATA;
1056 }
1057
1058 if (payload_length !=
1059 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1060 return PLDM_ERROR_INVALID_LENGTH;
1061 }
1062
1063 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
1064 !(event_class >= 0xF0 && event_class <= 0xFE)) {
1065 return PLDM_ERROR_INVALID_DATA;
1066 }
1067
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301068 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301069 header.msg_type = PLDM_REQUEST;
1070 header.instance = instance_id;
1071 header.pldm_type = PLDM_PLATFORM;
1072 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1073
1074 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1075 if (rc != PLDM_SUCCESS) {
1076 return rc;
1077 }
1078
1079 struct pldm_platform_event_message_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301080 (struct pldm_platform_event_message_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301081 request->format_version = format_version;
1082 request->tid = tid;
1083 request->event_class = event_class;
1084 memcpy(request->event_data, event_data, event_data_length);
1085
1086 return PLDM_SUCCESS;
1087}
1088
1089int decode_platform_event_message_resp(const struct pldm_msg *msg,
1090 size_t payload_length,
1091 uint8_t *completion_code,
1092 uint8_t *platform_event_status)
1093{
Andrew Jefferye5011772023-04-13 12:06:22 +09301094 struct pldm_msgbuf _buf;
1095 struct pldm_msgbuf *buf = &_buf;
1096 int rc;
1097
Andrew Jeffery9c766792022-08-10 23:12:49 +09301098 if (msg == NULL || completion_code == NULL ||
1099 platform_event_status == NULL) {
1100 return PLDM_ERROR_INVALID_DATA;
1101 }
1102
Andrew Jefferye5011772023-04-13 12:06:22 +09301103 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1104 msg->payload, payload_length);
1105 if (rc) {
1106 return rc;
1107 }
1108
1109 rc = pldm_msgbuf_extract(buf, completion_code);
1110 if (rc) {
1111 return rc;
1112 }
1113
Andrew Jeffery9c766792022-08-10 23:12:49 +09301114 if (PLDM_SUCCESS != *completion_code) {
1115 return PLDM_SUCCESS;
1116 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301117
Andrew Jefferye5011772023-04-13 12:06:22 +09301118 rc = pldm_msgbuf_extract(buf, platform_event_status);
1119 if (rc) {
1120 return rc;
1121 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301122
1123 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1124 return PLDM_ERROR_INVALID_DATA;
1125 }
1126
Andrew Jefferye5011772023-04-13 12:06:22 +09301127 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301128}
1129
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301130int encode_event_message_buffer_size_req(uint8_t instance_id,
1131 uint16_t event_receiver_max_buffer_size,
1132 struct pldm_msg *msg)
Dung Caod6ae8982022-11-02 10:00:10 +07001133{
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301134 struct pldm_header_info header = { 0 };
Dung Caod6ae8982022-11-02 10:00:10 +07001135 header.msg_type = PLDM_REQUEST;
1136 header.instance = instance_id;
1137 header.pldm_type = PLDM_PLATFORM;
1138 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1139
1140 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1141 if (rc != PLDM_SUCCESS) {
1142 return rc;
1143 }
1144
1145 struct pldm_event_message_buffer_size_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301146 (struct pldm_event_message_buffer_size_req *)msg->payload;
Dung Caod6ae8982022-11-02 10:00:10 +07001147 request->event_receiver_max_buffer_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301148 event_receiver_max_buffer_size;
Dung Caod6ae8982022-11-02 10:00:10 +07001149
1150 return PLDM_SUCCESS;
1151}
1152
1153int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1154 size_t payload_length,
1155 uint8_t *completion_code,
1156 uint16_t *terminus_max_buffer_size)
1157{
Andrew Jeffery11126902023-04-13 12:12:10 +09301158 struct pldm_msgbuf _buf;
1159 struct pldm_msgbuf *buf = &_buf;
1160 int rc;
1161
Dung Caod6ae8982022-11-02 10:00:10 +07001162 if (msg == NULL || completion_code == NULL ||
1163 terminus_max_buffer_size == NULL) {
1164 return PLDM_ERROR_INVALID_DATA;
1165 }
1166
Andrew Jeffery11126902023-04-13 12:12:10 +09301167 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1168 msg->payload, payload_length);
1169 if (rc) {
1170 return rc;
1171 }
1172
1173 rc = pldm_msgbuf_extract(buf, completion_code);
1174 if (rc) {
1175 return rc;
1176 }
1177
Dung Caod6ae8982022-11-02 10:00:10 +07001178 if (PLDM_SUCCESS != *completion_code) {
1179 return PLDM_SUCCESS;
1180 }
Dung Caod6ae8982022-11-02 10:00:10 +07001181
Andrew Jeffery11126902023-04-13 12:12:10 +09301182 pldm_msgbuf_extract(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001183
Andrew Jeffery11126902023-04-13 12:12:10 +09301184 return pldm_msgbuf_destroy_consumed(buf);
Dung Caod6ae8982022-11-02 10:00:10 +07001185}
1186
Dung Cao1bf8c872022-11-29 05:32:58 +07001187int encode_event_message_supported_req(uint8_t instance_id,
1188 uint8_t format_version,
1189 struct pldm_msg *msg)
1190{
1191 if (format_version != 1) {
1192 return PLDM_ERROR_INVALID_DATA;
1193 }
1194
1195 if (msg == NULL) {
1196 return PLDM_ERROR_INVALID_DATA;
1197 }
1198
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301199 struct pldm_header_info header = { 0 };
Dung Cao1bf8c872022-11-29 05:32:58 +07001200 header.msg_type = PLDM_REQUEST;
1201 header.instance = instance_id;
1202 header.pldm_type = PLDM_PLATFORM;
1203 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1204
1205 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1206 if (rc != PLDM_SUCCESS) {
1207 return rc;
1208 }
1209
1210 struct pldm_event_message_supported_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301211 (struct pldm_event_message_supported_req *)msg->payload;
Dung Cao1bf8c872022-11-29 05:32:58 +07001212 request->format_version = format_version;
1213
1214 return PLDM_SUCCESS;
1215}
1216
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301217int decode_event_message_supported_resp(const struct pldm_msg *msg,
1218 size_t payload_length,
1219 uint8_t *completion_code,
1220 uint8_t *synchrony_config,
1221 bitfield8_t *synchrony_config_support,
1222 uint8_t *number_event_class_returned,
1223 uint8_t *event_class,
1224 uint8_t event_class_count)
Dung Cao1bf8c872022-11-29 05:32:58 +07001225{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301226 struct pldm_msgbuf _buf;
1227 struct pldm_msgbuf *buf = &_buf;
1228 int i;
1229 int rc;
1230
Dung Cao1bf8c872022-11-29 05:32:58 +07001231 if (msg == NULL || completion_code == NULL ||
1232 synchrony_config == NULL || synchrony_config_support == NULL ||
1233 number_event_class_returned == NULL || event_class == NULL) {
1234 return PLDM_ERROR_INVALID_DATA;
1235 }
1236
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301237 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1238 msg->payload, payload_length);
1239 if (rc) {
1240 return rc;
1241 }
1242
1243 rc = pldm_msgbuf_extract(buf, completion_code);
1244 if (rc) {
1245 return rc;
1246 }
1247
Dung Cao1bf8c872022-11-29 05:32:58 +07001248 if (PLDM_SUCCESS != *completion_code) {
1249 return PLDM_SUCCESS;
1250 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301251
1252 rc = pldm_msgbuf_extract(buf, synchrony_config);
1253 if (rc) {
1254 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001255 }
1256
Dung Cao1bf8c872022-11-29 05:32:58 +07001257 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1258 return PLDM_ERROR_INVALID_DATA;
1259 }
1260
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301261 pldm_msgbuf_extract(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001262
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301263 rc = pldm_msgbuf_extract(buf, number_event_class_returned);
1264 if (rc) {
1265 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001266 }
1267
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301268 if (*number_event_class_returned == 0) {
1269 return pldm_msgbuf_destroy(buf);
1270 }
1271
1272 if (event_class_count < *number_event_class_returned) {
1273 return PLDM_ERROR_INVALID_LENGTH;
1274 }
1275
1276 for (i = 0; i < *number_event_class_returned; i++) {
1277 pldm_msgbuf_extract(buf, &event_class[i]);
1278 }
1279
1280 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao1bf8c872022-11-29 05:32:58 +07001281}
1282
Andrew Jeffery9c766792022-08-10 23:12:49 +09301283int decode_sensor_event_data(const uint8_t *event_data,
1284 size_t event_data_length, uint16_t *sensor_id,
1285 uint8_t *sensor_event_class_type,
1286 size_t *event_class_data_offset)
1287{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301288 struct pldm_msgbuf _buf;
1289 struct pldm_msgbuf *buf = &_buf;
1290 int rc;
1291
1292 rc = pldm_msgbuf_init(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1293 event_data, event_data_length);
1294 if (rc) {
1295 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301296 }
1297
1298 size_t event_class_data_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301299 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301300
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301301 pldm_msgbuf_extract(buf, sensor_id);
1302 rc = pldm_msgbuf_extract(buf, sensor_event_class_type);
1303 if (rc) {
1304 return rc;
1305 }
1306
1307 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301308 if (event_class_data_length !=
1309 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1310 return PLDM_ERROR_INVALID_LENGTH;
1311 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301312 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301313 if (event_class_data_length !=
1314 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1315 return PLDM_ERROR_INVALID_LENGTH;
1316 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301317 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301318 if (event_class_data_length <
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301319 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301320 event_class_data_length >
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301321 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301322 return PLDM_ERROR_INVALID_LENGTH;
1323 }
1324 } else {
1325 return PLDM_ERROR_INVALID_DATA;
1326 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301327
Andrew Jeffery9c766792022-08-10 23:12:49 +09301328 *event_class_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301329 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301330
1331 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301332}
1333
1334int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1335 uint8_t *present_op_state, uint8_t *previous_op_state)
1336{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301337 struct pldm_msgbuf _buf;
1338 struct pldm_msgbuf *buf = &_buf;
1339 int rc;
1340
1341 if (present_op_state == NULL || previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301342 return PLDM_ERROR_INVALID_DATA;
1343 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301344
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301345 rc = pldm_msgbuf_init(buf,
1346 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH,
1347 sensor_data, sensor_data_length);
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301348 if (rc) {
1349 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301350 }
1351
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301352 pldm_msgbuf_extract(buf, present_op_state);
1353 pldm_msgbuf_extract(buf, previous_op_state);
1354
1355 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301356}
1357
1358int decode_state_sensor_data(const uint8_t *sensor_data,
1359 size_t sensor_data_length, uint8_t *sensor_offset,
1360 uint8_t *event_state,
1361 uint8_t *previous_event_state)
1362{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301363 struct pldm_msgbuf _buf;
1364 struct pldm_msgbuf *buf = &_buf;
1365 int rc;
1366
1367 if (sensor_offset == NULL || event_state == NULL ||
1368 previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301369 return PLDM_ERROR_INVALID_DATA;
1370 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301371
1372 rc = pldm_msgbuf_init(buf,
1373 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1374 sensor_data, sensor_data_length);
1375 if (rc) {
1376 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301377 }
1378
Andrew Jeffery422790b2023-04-13 15:03:47 +09301379 pldm_msgbuf_extract(buf, sensor_offset);
1380 pldm_msgbuf_extract(buf, event_state);
1381 pldm_msgbuf_extract(buf, previous_event_state);
1382
1383 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301384}
1385
1386int decode_numeric_sensor_data(const uint8_t *sensor_data,
1387 size_t sensor_data_length, uint8_t *event_state,
1388 uint8_t *previous_event_state,
1389 uint8_t *sensor_data_size,
1390 uint32_t *present_reading)
1391{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301392 struct pldm_msgbuf _buf;
1393 struct pldm_msgbuf *buf = &_buf;
1394 int rc;
1395
1396 if (sensor_data_size == NULL || event_state == NULL ||
1397 previous_event_state == NULL || present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301398 return PLDM_ERROR_INVALID_DATA;
1399 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301400
1401 if (sensor_data_length >
1402 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301403 return PLDM_ERROR_INVALID_LENGTH;
1404 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301405
Andrew Jeffery155317e2023-04-13 18:36:51 +09301406 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301407 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1408 sensor_data, sensor_data_length);
Andrew Jeffery155317e2023-04-13 18:36:51 +09301409 if (rc) {
1410 return rc;
1411 }
1412
1413 pldm_msgbuf_extract(buf, event_state);
1414 pldm_msgbuf_extract(buf, previous_event_state);
1415 rc = pldm_msgbuf_extract(buf, sensor_data_size);
1416 if (rc) {
1417 return rc;
1418 }
1419
1420 /*
1421 * The implementation below is bonkers, but it's because the function
1422 * prototype is bonkers. The `present_reading` argument should have been
1423 * a tagged union.
1424 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301425 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301426 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1427 uint8_t val;
1428 if (!pldm_msgbuf_extract(buf, &val)) {
1429 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301430 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301431 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301432 }
1433 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1434 int8_t val;
1435 if (!pldm_msgbuf_extract(buf, &val)) {
1436 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301437 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301438 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301439 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301440 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301441 uint16_t val;
1442 if (!pldm_msgbuf_extract(buf, &val)) {
1443 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301444 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301445 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301446 }
1447 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301448 int16_t val;
1449 if (!pldm_msgbuf_extract(buf, &val)) {
1450 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301451 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301452 break;
1453 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301454 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1455 uint32_t val;
1456 if (!pldm_msgbuf_extract(buf, &val)) {
1457 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301458 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301459 break;
1460 }
1461 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1462 int32_t val;
1463 if (!pldm_msgbuf_extract(buf, &val)) {
1464 *present_reading = (uint32_t)val;
1465 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301466 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301467 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301468 default:
1469 return PLDM_ERROR_INVALID_DATA;
1470 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301471
1472 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301473}
1474
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301475#define PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE 69
1476int decode_numeric_sensor_pdr_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301477 const void *pdr_data, size_t pdr_data_length,
1478 struct pldm_numeric_sensor_value_pdr *pdr_value)
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301479{
1480 struct pldm_msgbuf _buf;
1481 struct pldm_msgbuf *buf = &_buf;
1482 int rc;
1483
1484 rc = pldm_msgbuf_init(buf, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1485 pdr_data, pdr_data_length);
1486 if (rc) {
1487 return rc;
1488 }
1489
1490 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1491 if (rc) {
1492 return rc;
1493 }
1494
1495 rc = pldm_platform_pdr_hdr_validate(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301496 &pdr_value->hdr, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1497 pdr_data_length);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301498 if (rc) {
1499 return rc;
1500 }
1501
1502 pldm_msgbuf_extract(buf, &pdr_value->terminus_handle);
1503 pldm_msgbuf_extract(buf, &pdr_value->sensor_id);
1504 pldm_msgbuf_extract(buf, &pdr_value->entity_type);
1505 pldm_msgbuf_extract(buf, &pdr_value->entity_instance_num);
1506 pldm_msgbuf_extract(buf, &pdr_value->container_id);
1507 pldm_msgbuf_extract(buf, &pdr_value->sensor_init);
1508 pldm_msgbuf_extract(buf, &pdr_value->sensor_auxiliary_names_pdr);
1509 pldm_msgbuf_extract(buf, &pdr_value->base_unit);
1510 pldm_msgbuf_extract(buf, &pdr_value->unit_modifier);
1511 pldm_msgbuf_extract(buf, &pdr_value->rate_unit);
1512 pldm_msgbuf_extract(buf, &pdr_value->base_oem_unit_handle);
1513 pldm_msgbuf_extract(buf, &pdr_value->aux_unit);
1514 pldm_msgbuf_extract(buf, &pdr_value->aux_unit_modifier);
1515 pldm_msgbuf_extract(buf, &pdr_value->aux_rate_unit);
1516 pldm_msgbuf_extract(buf, &pdr_value->rel);
1517 pldm_msgbuf_extract(buf, &pdr_value->aux_oem_unit_handle);
1518 pldm_msgbuf_extract(buf, &pdr_value->is_linear);
1519
1520 rc = pldm_msgbuf_extract(buf, &pdr_value->sensor_data_size);
1521 if (rc) {
1522 return rc;
1523 }
1524 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1525 return PLDM_ERROR_INVALID_DATA;
1526 }
1527
1528 pldm_msgbuf_extract(buf, &pdr_value->resolution);
1529 pldm_msgbuf_extract(buf, &pdr_value->offset);
1530 pldm_msgbuf_extract(buf, &pdr_value->accuracy);
1531 pldm_msgbuf_extract(buf, &pdr_value->plus_tolerance);
1532 pldm_msgbuf_extract(buf, &pdr_value->minus_tolerance);
1533 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1534 &pdr_value->hysteresis);
1535 pldm_msgbuf_extract(buf, &pdr_value->supported_thresholds.byte);
1536 pldm_msgbuf_extract(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301537 buf, &pdr_value->threshold_and_hysteresis_volatility.byte);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301538 pldm_msgbuf_extract(buf, &pdr_value->state_transition_interval);
1539 pldm_msgbuf_extract(buf, &pdr_value->update_interval);
1540 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1541 &pdr_value->max_readable);
1542 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1543 &pdr_value->min_readable);
1544
1545 rc = pldm_msgbuf_extract(buf, &pdr_value->range_field_format);
1546 if (rc) {
1547 return rc;
1548 }
1549 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1550 return PLDM_ERROR_INVALID_DATA;
1551 }
1552
1553 pldm_msgbuf_extract(buf, &pdr_value->range_field_support.byte);
1554 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301555 buf, pdr_value->range_field_format, &pdr_value->nominal_value);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301556 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301557 buf, pdr_value->range_field_format, &pdr_value->normal_max);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301558 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301559 buf, pdr_value->range_field_format, &pdr_value->normal_min);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301560 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301561 buf, pdr_value->range_field_format, &pdr_value->warning_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301562 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301563 buf, pdr_value->range_field_format, &pdr_value->warning_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301564 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301565 buf, pdr_value->range_field_format, &pdr_value->critical_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301566 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301567 buf, pdr_value->range_field_format, &pdr_value->critical_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301568 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301569 buf, pdr_value->range_field_format, &pdr_value->fatal_high);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301570 pldm_msgbuf_extract_range_field_format(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301571 buf, pdr_value->range_field_format, &pdr_value->fatal_low);
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301572
1573 return pldm_msgbuf_destroy(buf);
1574}
1575
Andrew Jeffery9c766792022-08-10 23:12:49 +09301576int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1577 uint16_t effecter_id,
1578 struct pldm_msg *msg)
1579{
1580 if (msg == NULL) {
1581 return PLDM_ERROR_INVALID_DATA;
1582 }
1583
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301584 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301585 header.msg_type = PLDM_REQUEST;
1586 header.instance = instance_id;
1587 header.pldm_type = PLDM_PLATFORM;
1588 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1589
1590 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1591 if (rc != PLDM_SUCCESS) {
1592 return rc;
1593 }
1594
1595 struct pldm_get_numeric_effecter_value_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301596 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301597 request->effecter_id = htole16(effecter_id);
1598
1599 return PLDM_SUCCESS;
1600}
1601
1602int encode_get_numeric_effecter_value_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301603 uint8_t instance_id, uint8_t completion_code,
1604 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1605 const uint8_t *pending_value, const uint8_t *present_value,
1606 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301607{
1608 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1609 return PLDM_ERROR_INVALID_DATA;
1610 }
1611
1612 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1613 return PLDM_ERROR_INVALID_DATA;
1614 }
1615
1616 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1617 return PLDM_ERROR_INVALID_DATA;
1618 }
1619
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301620 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301621 header.msg_type = PLDM_RESPONSE;
1622 header.instance = instance_id;
1623 header.pldm_type = PLDM_PLATFORM;
1624 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1625
1626 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1627 if (rc != PLDM_SUCCESS) {
1628 return rc;
1629 }
1630
1631 struct pldm_get_numeric_effecter_value_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301632 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301633
1634 response->completion_code = completion_code;
1635 response->effecter_data_size = effecter_data_size;
1636 response->effecter_oper_state = effecter_oper_state;
1637
1638 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1639 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1640 if (payload_length !=
1641 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1642 return PLDM_ERROR_INVALID_LENGTH;
1643 }
1644 response->pending_and_present_values[0] = *pending_value;
1645 response->pending_and_present_values[1] = *present_value;
1646
1647 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1648 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1649 if (payload_length !=
1650 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1651 return PLDM_ERROR_INVALID_LENGTH;
1652 }
1653 uint16_t val_pending = *(uint16_t *)pending_value;
1654 val_pending = htole16(val_pending);
1655 memcpy(response->pending_and_present_values, &val_pending,
1656 sizeof(uint16_t));
1657 uint16_t val_present = *(uint16_t *)present_value;
1658 val_present = htole16(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301659 memcpy((response->pending_and_present_values +
1660 sizeof(uint16_t)),
1661 &val_present, sizeof(uint16_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301662
1663 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1664 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1665 if (payload_length !=
1666 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1667 return PLDM_ERROR_INVALID_LENGTH;
1668 }
1669 uint32_t val_pending = *(uint32_t *)pending_value;
1670 val_pending = htole32(val_pending);
1671 memcpy(response->pending_and_present_values, &val_pending,
1672 sizeof(uint32_t));
1673 uint32_t val_present = *(uint32_t *)present_value;
1674 val_present = htole32(val_present);
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301675 memcpy((response->pending_and_present_values +
1676 sizeof(uint32_t)),
1677 &val_present, sizeof(uint32_t));
Andrew Jeffery9c766792022-08-10 23:12:49 +09301678 }
1679 return PLDM_SUCCESS;
1680}
1681
1682int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1683 size_t payload_length,
1684 uint16_t *effecter_id)
1685{
Andrew Jefferydd265822023-04-13 22:42:44 +09301686 struct pldm_msgbuf _buf;
1687 struct pldm_msgbuf *buf = &_buf;
1688 int rc;
1689
Andrew Jeffery9c766792022-08-10 23:12:49 +09301690 if (msg == NULL || effecter_id == NULL) {
1691 return PLDM_ERROR_INVALID_DATA;
1692 }
1693
Andrew Jefferydd265822023-04-13 22:42:44 +09301694 rc = pldm_msgbuf_init(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
1695 msg->payload, payload_length);
1696 if (rc) {
1697 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301698 }
1699
Andrew Jefferydd265822023-04-13 22:42:44 +09301700 pldm_msgbuf_extract(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301701
Andrew Jefferydd265822023-04-13 22:42:44 +09301702 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301703}
1704
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301705int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
1706 size_t payload_length,
1707 uint8_t *completion_code,
1708 uint8_t *effecter_data_size,
1709 uint8_t *effecter_oper_state,
1710 uint8_t *pending_value,
1711 uint8_t *present_value)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301712{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301713 struct pldm_msgbuf _buf;
1714 struct pldm_msgbuf *buf = &_buf;
1715 int rc;
1716
Andrew Jeffery9c766792022-08-10 23:12:49 +09301717 if (msg == NULL || effecter_data_size == NULL ||
1718 effecter_oper_state == NULL || pending_value == NULL ||
1719 present_value == NULL) {
1720 return PLDM_ERROR_INVALID_DATA;
1721 }
1722
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301723 rc = pldm_msgbuf_init(buf,
1724 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
1725 msg->payload, payload_length);
1726 if (rc) {
1727 return rc;
1728 }
1729
1730 rc = pldm_msgbuf_extract(buf, completion_code);
1731 if (rc) {
1732 return rc;
1733 }
1734
Andrew Jeffery9c766792022-08-10 23:12:49 +09301735 if (PLDM_SUCCESS != *completion_code) {
1736 return PLDM_SUCCESS;
1737 }
1738
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301739 rc = pldm_msgbuf_extract(buf, effecter_data_size);
1740 if (rc) {
1741 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301742 }
1743
Andrew Jeffery9c766792022-08-10 23:12:49 +09301744 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1745 return PLDM_ERROR_INVALID_DATA;
1746 }
1747
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301748 rc = pldm_msgbuf_extract(buf, effecter_oper_state);
1749 if (rc) {
1750 return rc;
1751 }
1752
Andrew Jeffery9c766792022-08-10 23:12:49 +09301753 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1754 return PLDM_ERROR_INVALID_DATA;
1755 }
1756
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301757 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1758 pending_value);
1759 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1760 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301761
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301762 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301763}
1764
1765int encode_pldm_pdr_repository_chg_event_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301766 uint8_t event_data_format, uint8_t number_of_change_records,
1767 const uint8_t *event_data_operations,
1768 const uint8_t *numbers_of_change_entries,
1769 const uint32_t *const *change_entries,
1770 struct pldm_pdr_repository_chg_event_data *event_data,
1771 size_t *actual_change_records_size, size_t max_change_records_size)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301772{
1773 if (event_data_operations == NULL ||
1774 numbers_of_change_entries == NULL || change_entries == NULL) {
1775 return PLDM_ERROR_INVALID_DATA;
1776 }
1777
1778 size_t expected_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301779 sizeof(event_data_format) + sizeof(number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301780
1781 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301782 sizeof(*event_data_operations) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301783 expected_size +=
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301784 sizeof(*numbers_of_change_entries) * number_of_change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301785
1786 for (uint8_t i = 0; i < number_of_change_records; ++i) {
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301787 expected_size += sizeof(*change_entries[0]) *
1788 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301789 }
1790
1791 *actual_change_records_size = expected_size;
1792
1793 if (event_data == NULL) {
1794 return PLDM_SUCCESS;
1795 }
1796
1797 if (max_change_records_size < expected_size) {
1798 return PLDM_ERROR_INVALID_LENGTH;
1799 }
1800
1801 event_data->event_data_format = event_data_format;
1802 event_data->number_of_change_records = number_of_change_records;
1803
1804 struct pldm_pdr_repository_change_record_data *record_data =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301805 (struct pldm_pdr_repository_change_record_data *)
1806 event_data->change_records;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301807
1808 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1809 record_data->event_data_operation = event_data_operations[i];
1810 record_data->number_of_change_entries =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301811 numbers_of_change_entries[i];
Andrew Jeffery9c766792022-08-10 23:12:49 +09301812
1813 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1814 ++j) {
1815 record_data->change_entry[j] =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301816 htole32(change_entries[i][j]);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301817 }
1818
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301819 record_data =
1820 (struct pldm_pdr_repository_change_record_data
1821 *)(record_data->change_entry +
1822 record_data->number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301823 }
1824
1825 return PLDM_SUCCESS;
1826}
1827
1828int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1829 size_t event_data_size,
1830 uint8_t *event_data_format,
1831 uint8_t *number_of_change_records,
1832 size_t *change_record_data_offset)
1833{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301834 struct pldm_msgbuf _buf;
1835 struct pldm_msgbuf *buf = &_buf;
1836 int rc;
1837
1838 if (event_data_format == NULL || number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301839 change_record_data_offset == NULL) {
1840 return PLDM_ERROR_INVALID_DATA;
1841 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301842
1843 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
1844 event_data, event_data_size);
1845 if (rc) {
1846 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301847 }
1848
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301849 pldm_msgbuf_extract(buf, event_data_format);
1850 pldm_msgbuf_extract(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301851
Andrew Jeffery9c766792022-08-10 23:12:49 +09301852 *change_record_data_offset =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301853 sizeof(*event_data_format) + sizeof(*number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301854
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301855 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301856}
1857
1858int decode_pldm_pdr_repository_change_record_data(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301859 const uint8_t *change_record_data, size_t change_record_data_size,
1860 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1861 size_t *change_entry_data_offset)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301862{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301863 struct pldm_msgbuf _buf;
1864 struct pldm_msgbuf *buf = &_buf;
1865 int rc;
1866
1867 if (event_data_operation == NULL || number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301868 change_entry_data_offset == NULL) {
1869 return PLDM_ERROR_INVALID_DATA;
1870 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301871
1872 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
1873 change_record_data, change_record_data_size);
1874 if (rc) {
1875 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301876 }
1877
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301878 pldm_msgbuf_extract(buf, event_data_operation);
1879 pldm_msgbuf_extract(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301880
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301881 *change_entry_data_offset = sizeof(*event_data_operation) +
1882 sizeof(*number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301883
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301884 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301885}
1886
1887int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1888 uint8_t rearm_event_state,
1889 struct pldm_msg *msg)
1890{
1891 if (msg == NULL) {
1892 return PLDM_ERROR_INVALID_DATA;
1893 }
1894
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301895 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301896 header.msg_type = PLDM_REQUEST;
1897 header.instance = instance_id;
1898 header.pldm_type = PLDM_PLATFORM;
1899 header.command = PLDM_GET_SENSOR_READING;
1900
1901 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1902 if (rc != PLDM_SUCCESS) {
1903 return rc;
1904 }
1905
1906 struct pldm_get_sensor_reading_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301907 (struct pldm_get_sensor_reading_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301908
1909 request->sensor_id = htole16(sensor_id);
1910 request->rearm_event_state = rearm_event_state;
1911
1912 return PLDM_SUCCESS;
1913}
1914
1915int decode_get_sensor_reading_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301916 const struct pldm_msg *msg, size_t payload_length,
1917 uint8_t *completion_code, uint8_t *sensor_data_size,
1918 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
1919 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
1920 uint8_t *present_reading)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301921{
Andrew Jeffery840b1402023-04-13 23:54:44 +09301922 struct pldm_msgbuf _buf;
1923 struct pldm_msgbuf *buf = &_buf;
1924 int rc;
1925
Andrew Jeffery9c766792022-08-10 23:12:49 +09301926 if (msg == NULL || completion_code == NULL ||
1927 sensor_data_size == NULL || sensor_operational_state == NULL ||
1928 sensor_event_message_enable == NULL || present_state == NULL ||
1929 previous_state == NULL || event_state == NULL ||
1930 present_reading == NULL) {
1931 return PLDM_ERROR_INVALID_DATA;
1932 }
1933
Andrew Jeffery840b1402023-04-13 23:54:44 +09301934 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
1935 msg->payload, payload_length);
1936 if (rc) {
1937 return rc;
1938 }
1939
1940 rc = pldm_msgbuf_extract(buf, completion_code);
1941 if (rc) {
1942 return rc;
1943 }
1944
Andrew Jeffery9c766792022-08-10 23:12:49 +09301945 if (PLDM_SUCCESS != *completion_code) {
1946 return PLDM_SUCCESS;
1947 }
1948
Andrew Jeffery840b1402023-04-13 23:54:44 +09301949 rc = pldm_msgbuf_extract(buf, sensor_data_size);
1950 if (rc) {
1951 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301952 }
1953
Andrew Jeffery840b1402023-04-13 23:54:44 +09301954 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301955 return PLDM_ERROR_INVALID_DATA;
1956 }
1957
Andrew Jeffery840b1402023-04-13 23:54:44 +09301958 pldm_msgbuf_extract(buf, sensor_operational_state);
1959 pldm_msgbuf_extract(buf, sensor_event_message_enable);
1960 pldm_msgbuf_extract(buf, present_state);
1961 pldm_msgbuf_extract(buf, previous_state);
1962 pldm_msgbuf_extract(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301963
Andrew Jeffery840b1402023-04-13 23:54:44 +09301964 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
1965 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301966
Andrew Jeffery840b1402023-04-13 23:54:44 +09301967 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301968}
1969
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301970int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
1971 uint8_t sensor_data_size,
1972 uint8_t sensor_operational_state,
1973 uint8_t sensor_event_message_enable,
1974 uint8_t present_state,
1975 uint8_t previous_state, uint8_t event_state,
1976 const uint8_t *present_reading,
1977 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301978{
1979 if (msg == NULL || present_reading == NULL) {
1980 return PLDM_ERROR_INVALID_DATA;
1981 }
1982
1983 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1984 return PLDM_ERROR_INVALID_DATA;
1985 }
1986
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301987 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09301988 header.msg_type = PLDM_RESPONSE;
1989 header.instance = instance_id;
1990 header.pldm_type = PLDM_PLATFORM;
1991 header.command = PLDM_GET_SENSOR_READING;
1992
1993 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1994 if (rc != PLDM_SUCCESS) {
1995 return rc;
1996 }
1997
1998 struct pldm_get_sensor_reading_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09301999 (struct pldm_get_sensor_reading_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302000
2001 response->completion_code = completion_code;
2002 response->sensor_data_size = sensor_data_size;
2003 response->sensor_operational_state = sensor_operational_state;
2004 response->sensor_event_message_enable = sensor_event_message_enable;
2005 response->present_state = present_state;
2006 response->previous_state = previous_state;
2007 response->event_state = event_state;
2008
2009 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2010 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2011 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2012 return PLDM_ERROR_INVALID_LENGTH;
2013 }
2014 response->present_reading[0] = *present_reading;
2015
2016 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2017 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2018 if (payload_length !=
2019 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2020 return PLDM_ERROR_INVALID_LENGTH;
2021 }
2022 uint16_t val = *(uint16_t *)present_reading;
2023 val = htole16(val);
2024 memcpy(response->present_reading, &val, 2);
2025
2026 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2027 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2028 if (payload_length !=
2029 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2030 return PLDM_ERROR_INVALID_LENGTH;
2031 }
2032 uint32_t val = *(uint32_t *)present_reading;
2033 val = htole32(val);
2034 memcpy(response->present_reading, &val, 4);
2035 }
2036
2037 return PLDM_SUCCESS;
2038}
2039
2040int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2041 size_t payload_length, uint16_t *sensor_id,
2042 uint8_t *rearm_event_state)
2043{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302044 struct pldm_msgbuf _buf;
2045 struct pldm_msgbuf *buf = &_buf;
2046 int rc;
2047
Andrew Jeffery9c766792022-08-10 23:12:49 +09302048 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2049 return PLDM_ERROR_INVALID_DATA;
2050 }
2051
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302052 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2053 msg->payload, payload_length);
2054 if (rc) {
2055 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302056 }
2057
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302058 pldm_msgbuf_extract(buf, sensor_id);
2059 pldm_msgbuf_extract(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302060
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09302061 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302062}
2063
2064int encode_set_event_receiver_req(uint8_t instance_id,
2065 uint8_t event_message_global_enable,
2066 uint8_t transport_protocol_type,
2067 uint8_t event_receiver_address_info,
2068 uint16_t heartbeat_timer,
2069 struct pldm_msg *msg)
2070{
2071 if (msg == NULL) {
2072 return PLDM_ERROR_INVALID_DATA;
2073 }
2074
2075 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2076 return PLDM_ERROR_INVALID_DATA;
2077 }
2078
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302079 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302080 header.msg_type = PLDM_REQUEST;
2081 header.instance = instance_id;
2082 header.pldm_type = PLDM_PLATFORM;
2083 header.command = PLDM_SET_EVENT_RECEIVER;
2084
2085 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2086 if (rc != PLDM_SUCCESS) {
2087 return rc;
2088 }
2089
2090 struct pldm_set_event_receiver_req *request =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302091 (struct pldm_set_event_receiver_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302092 request->event_message_global_enable = event_message_global_enable;
2093
2094 request->transport_protocol_type = transport_protocol_type;
2095 request->event_receiver_address_info = event_receiver_address_info;
2096
2097 if (event_message_global_enable ==
2098 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2099 if (heartbeat_timer == 0) {
2100 return PLDM_ERROR_INVALID_DATA;
2101 }
2102 request->heartbeat_timer = htole16(heartbeat_timer);
2103 }
2104
2105 return PLDM_SUCCESS;
2106}
2107
2108int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2109 size_t payload_length,
2110 uint8_t *completion_code)
2111{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302112 struct pldm_msgbuf _buf;
2113 struct pldm_msgbuf *buf = &_buf;
2114 int rc;
2115
Andrew Jeffery9c766792022-08-10 23:12:49 +09302116 if (msg == NULL || completion_code == NULL) {
2117 return PLDM_ERROR_INVALID_DATA;
2118 }
2119
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302120 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2121 msg->payload, payload_length);
2122 if (rc) {
2123 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302124 }
2125
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302126 pldm_msgbuf_extract(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302127
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09302128 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302129}
2130
2131int decode_set_event_receiver_req(const struct pldm_msg *msg,
2132 size_t payload_length,
2133 uint8_t *event_message_global_enable,
2134 uint8_t *transport_protocol_type,
2135 uint8_t *event_receiver_address_info,
2136 uint16_t *heartbeat_timer)
2137
2138{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302139 struct pldm_msgbuf _buf;
2140 struct pldm_msgbuf *buf = &_buf;
2141 int rc;
2142
Andrew Jeffery9c766792022-08-10 23:12:49 +09302143 if (msg == NULL || event_message_global_enable == NULL ||
2144 transport_protocol_type == NULL ||
2145 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2146 return PLDM_ERROR_INVALID_DATA;
2147 }
2148
Andrew Jeffery9667f582023-04-14 00:39:21 +09302149 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2150 msg->payload, payload_length);
2151 if (rc) {
2152 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302153 }
2154
Andrew Jeffery9667f582023-04-14 00:39:21 +09302155 pldm_msgbuf_extract(buf, event_message_global_enable);
2156 pldm_msgbuf_extract(buf, transport_protocol_type);
2157 pldm_msgbuf_extract(buf, event_receiver_address_info);
2158 pldm_msgbuf_extract(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302159
Andrew Jeffery9667f582023-04-14 00:39:21 +09302160 rc = pldm_msgbuf_destroy(buf);
2161 if (rc) {
2162 return rc;
2163 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302164
Andrew Jeffery9c766792022-08-10 23:12:49 +09302165 if ((*event_message_global_enable ==
2166 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2167 (*heartbeat_timer == 0)) {
2168 return PLDM_ERROR_INVALID_DATA;
2169 }
2170
Andrew Jeffery9c766792022-08-10 23:12:49 +09302171 return PLDM_SUCCESS;
2172}
2173
2174int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2175 struct pldm_msg *msg)
2176
2177{
2178 if (msg == NULL) {
2179 return PLDM_ERROR_INVALID_DATA;
2180 }
2181
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302182 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +09302183 header.instance = instance_id;
2184 header.msg_type = PLDM_RESPONSE;
2185 header.pldm_type = PLDM_PLATFORM;
2186 header.command = PLDM_SET_EVENT_RECEIVER;
2187
2188 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2189 if (rc != PLDM_SUCCESS) {
2190 return rc;
2191 }
2192
2193 msg->payload[0] = completion_code;
2194
2195 return PLDM_SUCCESS;
2196}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002197
2198int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2199 uint8_t format_version,
2200 uint8_t transfer_operation_flag,
2201 uint32_t data_transfer_handle,
2202 uint16_t event_id_to_acknowledge,
2203 struct pldm_msg *msg,
2204 size_t payload_length)
2205{
2206 struct pldm_msgbuf _buf;
2207 struct pldm_msgbuf *buf = &_buf;
2208 int rc;
2209
2210 if (msg == NULL) {
2211 return PLDM_ERROR_INVALID_DATA;
2212 }
2213
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302214 struct pldm_header_info header = { 0 };
Thu Nguyen159a98b2022-11-02 10:00:10 +07002215 header.msg_type = PLDM_REQUEST;
2216 header.instance = instance_id;
2217 header.pldm_type = PLDM_PLATFORM;
2218 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2219
2220 rc = pack_pldm_header(&header, &(msg->hdr));
2221 if (rc != PLDM_SUCCESS) {
2222 return rc;
2223 }
2224
2225 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302226 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2227 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002228 if (rc) {
2229 return rc;
2230 }
2231
2232 pldm_msgbuf_insert(buf, format_version);
2233 pldm_msgbuf_insert(buf, transfer_operation_flag);
2234 pldm_msgbuf_insert(buf, data_transfer_handle);
2235 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2236
2237 return pldm_msgbuf_destroy(buf);
2238}
2239
2240int decode_poll_for_platform_event_message_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302241 const struct pldm_msg *msg, size_t payload_length,
2242 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2243 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2244 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2245 uint32_t *event_data_integrity_checksum)
Thu Nguyen159a98b2022-11-02 10:00:10 +07002246{
2247 struct pldm_msgbuf _buf;
2248 struct pldm_msgbuf *buf = &_buf;
2249 int rc;
2250
2251 if (msg == NULL || completion_code == NULL || tid == NULL ||
2252 event_id == NULL || next_data_transfer_handle == NULL ||
2253 transfer_flag == NULL || event_class == NULL ||
2254 event_data_size == NULL || event_data == NULL ||
2255 event_data_integrity_checksum == NULL) {
2256 return PLDM_ERROR_INVALID_DATA;
2257 }
2258
2259 rc = pldm_msgbuf_init(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +09302260 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2261 msg->payload, payload_length);
Thu Nguyen159a98b2022-11-02 10:00:10 +07002262 if (rc) {
2263 return rc;
2264 }
2265
2266 rc = pldm_msgbuf_extract(buf, completion_code);
2267 if (rc) {
2268 return rc;
2269 }
2270 if (PLDM_SUCCESS != *completion_code) {
2271 return *completion_code;
2272 }
2273
2274 pldm_msgbuf_extract(buf, tid);
2275 rc = pldm_msgbuf_extract(buf, event_id);
2276 if (rc) {
2277 return rc;
2278 }
2279 if ((*event_id == 0) || (*event_id == 0xffff)) {
2280 return PLDM_SUCCESS;
2281 }
2282
2283 pldm_msgbuf_extract(buf, next_data_transfer_handle);
2284 rc = pldm_msgbuf_extract(buf, transfer_flag);
2285 if (rc) {
2286 return rc;
2287 }
2288
2289 pldm_msgbuf_extract(buf, event_class);
2290 rc = pldm_msgbuf_extract(buf, event_data_size);
2291 if (rc) {
2292 return rc;
2293 }
2294 if (*event_data_size > payload_length) {
2295 return PLDM_ERROR_INVALID_DATA;
2296 }
2297
2298 if (*event_data_size > 0) {
2299 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2300 }
2301
2302 if (*transfer_flag == PLDM_END ||
2303 *transfer_flag == PLDM_START_AND_END) {
2304 pldm_msgbuf_extract(buf, event_data_integrity_checksum);
2305 }
2306
2307 return pldm_msgbuf_destroy_consumed(buf);
2308}