148761c62SAndrew Jeffery /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2830c1eb4SAndrew Jeffery #include "api.h" 3830c1eb4SAndrew Jeffery #include "compiler.h" 4f490a38fSTal Yacobi #include "dsp/base.h" 548761c62SAndrew Jeffery #include "msgbuf.h" 648761c62SAndrew Jeffery #include "msgbuf/platform.h" 748761c62SAndrew Jeffery 848761c62SAndrew Jeffery #include <libpldm/base.h> 948761c62SAndrew Jeffery #include <libpldm/platform.h> 1048761c62SAndrew Jeffery #include <libpldm/pldm_types.h> 1148761c62SAndrew Jeffery 1248761c62SAndrew Jeffery #include <endian.h> 1348761c62SAndrew Jeffery #include <stdint.h> 1448761c62SAndrew Jeffery #include <stdlib.h> 1548761c62SAndrew Jeffery #include <string.h> 16dacfa354SThu Nguyen #include <uchar.h> 1748761c62SAndrew Jeffery 1848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 1948761c62SAndrew Jeffery int encode_state_effecter_pdr( 2048761c62SAndrew Jeffery struct pldm_state_effecter_pdr *const effecter, 2148761c62SAndrew Jeffery const size_t allocation_size, 2248761c62SAndrew Jeffery const struct state_effecter_possible_states *const possible_states, 2348761c62SAndrew Jeffery const size_t possible_states_size, size_t *const actual_size) 2448761c62SAndrew Jeffery { 2548761c62SAndrew Jeffery size_t calculated_possible_states_size = 0; 2648761c62SAndrew Jeffery 27ad33b99aSAndrew Jeffery if (!effecter || !possible_states || !actual_size) { 28ad33b99aSAndrew Jeffery return PLDM_ERROR; 29ad33b99aSAndrew Jeffery } 30ad33b99aSAndrew Jeffery 31ad33b99aSAndrew Jeffery if (SIZE_MAX - (sizeof(*effecter) - sizeof(effecter->possible_states) < 32ad33b99aSAndrew Jeffery possible_states_size)) { 33ad33b99aSAndrew Jeffery return PLDM_ERROR; 34ad33b99aSAndrew Jeffery } 35ad33b99aSAndrew Jeffery 36ad33b99aSAndrew Jeffery if (allocation_size < 37ad33b99aSAndrew Jeffery (sizeof(*effecter) - sizeof(effecter->possible_states)) + 38ad33b99aSAndrew Jeffery possible_states_size) { 39ad33b99aSAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 40ad33b99aSAndrew Jeffery } 41ad33b99aSAndrew Jeffery 42ad33b99aSAndrew Jeffery // Encode possible states 43ad33b99aSAndrew Jeffery 4448761c62SAndrew Jeffery { 4548761c62SAndrew Jeffery char *states_ptr = (char *)possible_states; 4648761c62SAndrew Jeffery char *const begin_states_ptr = states_ptr; 4748761c62SAndrew Jeffery 4848761c62SAndrew Jeffery for (int i = 0; i < effecter->composite_effecter_count; ++i) { 4948761c62SAndrew Jeffery struct state_effecter_possible_states *states = 5048761c62SAndrew Jeffery (struct state_effecter_possible_states *) 5148761c62SAndrew Jeffery states_ptr; 5248761c62SAndrew Jeffery 5348761c62SAndrew Jeffery HTOLE16(states->state_set_id); 5448761c62SAndrew Jeffery 5548761c62SAndrew Jeffery states_ptr += 5648761c62SAndrew Jeffery (sizeof(*states) - sizeof(states->states) + 5748761c62SAndrew Jeffery states->possible_states_size); 5848761c62SAndrew Jeffery } 5948761c62SAndrew Jeffery 6048761c62SAndrew Jeffery calculated_possible_states_size = states_ptr - begin_states_ptr; 6148761c62SAndrew Jeffery } 6248761c62SAndrew Jeffery 6348761c62SAndrew Jeffery // Check lengths 6448761c62SAndrew Jeffery 6548761c62SAndrew Jeffery if (possible_states_size != calculated_possible_states_size) { 6648761c62SAndrew Jeffery *actual_size = 0; 6748761c62SAndrew Jeffery return PLDM_ERROR; 6848761c62SAndrew Jeffery } 6948761c62SAndrew Jeffery 7048761c62SAndrew Jeffery *actual_size = 7148761c62SAndrew Jeffery (sizeof(struct pldm_state_effecter_pdr) + possible_states_size - 7248761c62SAndrew Jeffery sizeof(effecter->possible_states)); 7348761c62SAndrew Jeffery 7448761c62SAndrew Jeffery // Encode rest of PDR 7548761c62SAndrew Jeffery 7648761c62SAndrew Jeffery effecter->hdr.version = 1; 7748761c62SAndrew Jeffery effecter->hdr.type = PLDM_STATE_EFFECTER_PDR; 7848761c62SAndrew Jeffery effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 7948761c62SAndrew Jeffery 8048761c62SAndrew Jeffery memcpy(effecter->possible_states, possible_states, 8148761c62SAndrew Jeffery possible_states_size); 8248761c62SAndrew Jeffery 8348761c62SAndrew Jeffery // Convert effecter PDR body 8448761c62SAndrew Jeffery HTOLE16(effecter->terminus_handle); 8548761c62SAndrew Jeffery HTOLE16(effecter->effecter_id); 8648761c62SAndrew Jeffery HTOLE16(effecter->entity_type); 8748761c62SAndrew Jeffery HTOLE16(effecter->entity_instance); 8848761c62SAndrew Jeffery HTOLE16(effecter->container_id); 8948761c62SAndrew Jeffery HTOLE16(effecter->effecter_semantic_id); 9048761c62SAndrew Jeffery 9148761c62SAndrew Jeffery // Convert header 9248761c62SAndrew Jeffery HTOLE32(effecter->hdr.record_handle); 9348761c62SAndrew Jeffery HTOLE16(effecter->hdr.record_change_num); 9448761c62SAndrew Jeffery HTOLE16(effecter->hdr.length); 9548761c62SAndrew Jeffery 9648761c62SAndrew Jeffery return PLDM_SUCCESS; 9748761c62SAndrew Jeffery } 9848761c62SAndrew Jeffery 9948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 10048761c62SAndrew Jeffery int encode_state_sensor_pdr( 10148761c62SAndrew Jeffery struct pldm_state_sensor_pdr *const sensor, 10248761c62SAndrew Jeffery const size_t allocation_size, 10348761c62SAndrew Jeffery const struct state_sensor_possible_states *const possible_states, 10448761c62SAndrew Jeffery const size_t possible_states_size, size_t *const actual_size) 10548761c62SAndrew Jeffery { 10648761c62SAndrew Jeffery size_t calculated_possible_states_size = 0; 10748761c62SAndrew Jeffery 108bb50a590SAndrew Jeffery if (!sensor || !possible_states || !actual_size) { 109bb50a590SAndrew Jeffery return PLDM_ERROR; 110bb50a590SAndrew Jeffery } 111bb50a590SAndrew Jeffery 112bb50a590SAndrew Jeffery if (SIZE_MAX - (sizeof(*sensor) - sizeof(sensor->possible_states)) < 113bb50a590SAndrew Jeffery possible_states_size) { 114bb50a590SAndrew Jeffery return PLDM_ERROR; 115bb50a590SAndrew Jeffery } 116bb50a590SAndrew Jeffery 117bb50a590SAndrew Jeffery if (allocation_size < 118bb50a590SAndrew Jeffery (sizeof(*sensor) - sizeof(sensor->possible_states) + 119bb50a590SAndrew Jeffery possible_states_size)) { 120bb50a590SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 121bb50a590SAndrew Jeffery } 122bb50a590SAndrew Jeffery 12348761c62SAndrew Jeffery { 124bb50a590SAndrew Jeffery // Encode possible states 12548761c62SAndrew Jeffery char *states_ptr = (char *)possible_states; 12648761c62SAndrew Jeffery char *const begin_states_ptr = states_ptr; 12748761c62SAndrew Jeffery 12848761c62SAndrew Jeffery for (int i = 0; i < sensor->composite_sensor_count; ++i) { 12948761c62SAndrew Jeffery struct state_sensor_possible_states *states = 13048761c62SAndrew Jeffery (struct state_sensor_possible_states *) 13148761c62SAndrew Jeffery states_ptr; 13248761c62SAndrew Jeffery 13348761c62SAndrew Jeffery HTOLE16(states->state_set_id); 13448761c62SAndrew Jeffery 13548761c62SAndrew Jeffery states_ptr += 13648761c62SAndrew Jeffery (sizeof(*states) - sizeof(states->states) + 13748761c62SAndrew Jeffery states->possible_states_size); 13848761c62SAndrew Jeffery } 13948761c62SAndrew Jeffery 14048761c62SAndrew Jeffery calculated_possible_states_size = states_ptr - begin_states_ptr; 14148761c62SAndrew Jeffery } 14248761c62SAndrew Jeffery 14348761c62SAndrew Jeffery // Check lengths 14448761c62SAndrew Jeffery 14548761c62SAndrew Jeffery if (possible_states_size != calculated_possible_states_size) { 14648761c62SAndrew Jeffery *actual_size = 0; 14748761c62SAndrew Jeffery return PLDM_ERROR; 14848761c62SAndrew Jeffery } 14948761c62SAndrew Jeffery 15048761c62SAndrew Jeffery *actual_size = (sizeof(struct pldm_state_sensor_pdr) + 15148761c62SAndrew Jeffery possible_states_size - sizeof(sensor->possible_states)); 15248761c62SAndrew Jeffery 15348761c62SAndrew Jeffery // Encode rest of PDR 15448761c62SAndrew Jeffery 15548761c62SAndrew Jeffery sensor->hdr.version = 1; 15648761c62SAndrew Jeffery sensor->hdr.type = PLDM_STATE_SENSOR_PDR; 15748761c62SAndrew Jeffery sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr); 15848761c62SAndrew Jeffery 15948761c62SAndrew Jeffery memcpy(sensor->possible_states, possible_states, possible_states_size); 16048761c62SAndrew Jeffery 16148761c62SAndrew Jeffery // Convert sensor PDR body 16248761c62SAndrew Jeffery HTOLE16(sensor->terminus_handle); 16348761c62SAndrew Jeffery HTOLE16(sensor->sensor_id); 16448761c62SAndrew Jeffery HTOLE16(sensor->entity_type); 16548761c62SAndrew Jeffery HTOLE16(sensor->entity_instance); 16648761c62SAndrew Jeffery HTOLE16(sensor->container_id); 16748761c62SAndrew Jeffery 16848761c62SAndrew Jeffery // Convert header 16948761c62SAndrew Jeffery HTOLE32(sensor->hdr.record_handle); 17048761c62SAndrew Jeffery HTOLE16(sensor->hdr.record_change_num); 17148761c62SAndrew Jeffery HTOLE16(sensor->hdr.length); 17248761c62SAndrew Jeffery 17348761c62SAndrew Jeffery return PLDM_SUCCESS; 17448761c62SAndrew Jeffery } 17548761c62SAndrew Jeffery 17648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 17748761c62SAndrew Jeffery int encode_set_state_effecter_states_resp(uint8_t instance_id, 17848761c62SAndrew Jeffery uint8_t completion_code, 17948761c62SAndrew Jeffery struct pldm_msg *msg) 18048761c62SAndrew Jeffery { 18148761c62SAndrew Jeffery if (msg == NULL) { 18248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 18348761c62SAndrew Jeffery } 18448761c62SAndrew Jeffery 18548761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 18648761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 18748761c62SAndrew Jeffery header.instance = instance_id; 18848761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 18948761c62SAndrew Jeffery header.command = PLDM_SET_STATE_EFFECTER_STATES; 19048761c62SAndrew Jeffery 19148761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 19248761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 19348761c62SAndrew Jeffery return rc; 19448761c62SAndrew Jeffery } 19548761c62SAndrew Jeffery 19648761c62SAndrew Jeffery msg->payload[0] = completion_code; 19748761c62SAndrew Jeffery 19848761c62SAndrew Jeffery return PLDM_SUCCESS; 19948761c62SAndrew Jeffery } 20048761c62SAndrew Jeffery 20148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 20248761c62SAndrew Jeffery int encode_set_state_effecter_states_req(uint8_t instance_id, 20348761c62SAndrew Jeffery uint16_t effecter_id, 20448761c62SAndrew Jeffery uint8_t comp_effecter_count, 20548761c62SAndrew Jeffery set_effecter_state_field *field, 20648761c62SAndrew Jeffery struct pldm_msg *msg) 20748761c62SAndrew Jeffery { 20848761c62SAndrew Jeffery if (msg == NULL) { 20948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 21048761c62SAndrew Jeffery } 21148761c62SAndrew Jeffery 21248761c62SAndrew Jeffery if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 || 21348761c62SAndrew Jeffery field == NULL) { 21448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 21548761c62SAndrew Jeffery } 21648761c62SAndrew Jeffery 21748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 21848761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 21948761c62SAndrew Jeffery header.instance = instance_id; 22048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 22148761c62SAndrew Jeffery header.command = PLDM_SET_STATE_EFFECTER_STATES; 22248761c62SAndrew Jeffery 22348761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 22448761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 22548761c62SAndrew Jeffery return rc; 22648761c62SAndrew Jeffery } 22748761c62SAndrew Jeffery 22848761c62SAndrew Jeffery struct pldm_set_state_effecter_states_req *request = 22948761c62SAndrew Jeffery (struct pldm_set_state_effecter_states_req *)msg->payload; 23048761c62SAndrew Jeffery effecter_id = htole16(effecter_id); 23148761c62SAndrew Jeffery request->effecter_id = effecter_id; 23248761c62SAndrew Jeffery request->comp_effecter_count = comp_effecter_count; 23348761c62SAndrew Jeffery memcpy(request->field, field, 23448761c62SAndrew Jeffery (sizeof(set_effecter_state_field) * comp_effecter_count)); 23548761c62SAndrew Jeffery 23648761c62SAndrew Jeffery return PLDM_SUCCESS; 23748761c62SAndrew Jeffery } 23848761c62SAndrew Jeffery 23948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 24048761c62SAndrew Jeffery int decode_set_state_effecter_states_resp(const struct pldm_msg *msg, 24148761c62SAndrew Jeffery size_t payload_length, 24248761c62SAndrew Jeffery uint8_t *completion_code) 24348761c62SAndrew Jeffery { 24448761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 24548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 24648761c62SAndrew Jeffery } 24748761c62SAndrew Jeffery 24848761c62SAndrew Jeffery *completion_code = msg->payload[0]; 24948761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 25048761c62SAndrew Jeffery return PLDM_SUCCESS; 25148761c62SAndrew Jeffery } 25248761c62SAndrew Jeffery 25348761c62SAndrew Jeffery if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) { 25448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 25548761c62SAndrew Jeffery } 25648761c62SAndrew Jeffery 25748761c62SAndrew Jeffery return PLDM_SUCCESS; 25848761c62SAndrew Jeffery } 25948761c62SAndrew Jeffery 26048761c62SAndrew Jeffery #define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3 26148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 26248761c62SAndrew Jeffery int decode_set_state_effecter_states_req(const struct pldm_msg *msg, 26348761c62SAndrew Jeffery size_t payload_length, 26448761c62SAndrew Jeffery uint16_t *effecter_id, 26548761c62SAndrew Jeffery uint8_t *comp_effecter_count, 26648761c62SAndrew Jeffery set_effecter_state_field *field) 26748761c62SAndrew Jeffery { 26848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 26948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 27048761c62SAndrew Jeffery int rc; 27148761c62SAndrew Jeffery int i; 27248761c62SAndrew Jeffery 27348761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL || 27448761c62SAndrew Jeffery field == NULL) { 27548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 27648761c62SAndrew Jeffery } 27748761c62SAndrew Jeffery 27848761c62SAndrew Jeffery if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) { 27948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 28048761c62SAndrew Jeffery } 28148761c62SAndrew Jeffery 282830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 283830c1eb4SAndrew Jeffery PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE, 28448761c62SAndrew Jeffery msg->payload, payload_length); 28548761c62SAndrew Jeffery if (rc) { 286830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 28748761c62SAndrew Jeffery } 28848761c62SAndrew Jeffery 28948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 29048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, comp_effecter_count); 29148761c62SAndrew Jeffery 29248761c62SAndrew Jeffery if (*comp_effecter_count > 8) { 29348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 29448761c62SAndrew Jeffery } 29548761c62SAndrew Jeffery 29648761c62SAndrew Jeffery for (i = 0; i < *comp_effecter_count; i++) { 29748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].set_request); 29848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].effecter_state); 29948761c62SAndrew Jeffery } 30048761c62SAndrew Jeffery 301830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 302830c1eb4SAndrew Jeffery if (rc) { 303830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 304830c1eb4SAndrew Jeffery } 305830c1eb4SAndrew Jeffery 306830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 30748761c62SAndrew Jeffery } 30848761c62SAndrew Jeffery 30948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 31048761c62SAndrew Jeffery int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length, 31148761c62SAndrew Jeffery uint32_t *record_hndl, uint32_t *data_transfer_hndl, 31248761c62SAndrew Jeffery uint8_t *transfer_op_flag, uint16_t *request_cnt, 31348761c62SAndrew Jeffery uint16_t *record_chg_num) 31448761c62SAndrew Jeffery { 31548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 31648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 31748761c62SAndrew Jeffery int rc; 31848761c62SAndrew Jeffery 31948761c62SAndrew Jeffery if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL || 32048761c62SAndrew Jeffery transfer_op_flag == NULL || request_cnt == NULL || 32148761c62SAndrew Jeffery record_chg_num == NULL) { 32248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 32348761c62SAndrew Jeffery } 32448761c62SAndrew Jeffery 32548761c62SAndrew Jeffery if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 32648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 32748761c62SAndrew Jeffery } 32848761c62SAndrew Jeffery 329830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload, 33048761c62SAndrew Jeffery payload_length); 33148761c62SAndrew Jeffery if (rc) { 332830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 33348761c62SAndrew Jeffery } 33448761c62SAndrew Jeffery 33548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_hndl); 33648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_hndl); 33748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_op_flag); 33848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, request_cnt); 33948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_chg_num); 34048761c62SAndrew Jeffery 341830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 342830c1eb4SAndrew Jeffery if (rc) { 343830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 344830c1eb4SAndrew Jeffery } 345830c1eb4SAndrew Jeffery 346830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 34748761c62SAndrew Jeffery } 34848761c62SAndrew Jeffery 349*36324f6bSAndrew Jeffery LIBPLDM_ABI_DEPRECATED_UNSAFE 35048761c62SAndrew Jeffery int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code, 35148761c62SAndrew Jeffery uint32_t next_record_hndl, 35248761c62SAndrew Jeffery uint32_t next_data_transfer_hndl, uint8_t transfer_flag, 35348761c62SAndrew Jeffery uint16_t resp_cnt, const uint8_t *record_data, 35448761c62SAndrew Jeffery uint8_t transfer_crc, struct pldm_msg *msg) 35548761c62SAndrew Jeffery { 35648761c62SAndrew Jeffery if (msg == NULL) { 35748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 35848761c62SAndrew Jeffery } 35948761c62SAndrew Jeffery 36048761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 36148761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 36248761c62SAndrew Jeffery header.instance = instance_id; 36348761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 36448761c62SAndrew Jeffery header.command = PLDM_GET_PDR; 36548761c62SAndrew Jeffery 36648761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 36748761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 36848761c62SAndrew Jeffery return rc; 36948761c62SAndrew Jeffery } 37048761c62SAndrew Jeffery 37148761c62SAndrew Jeffery struct pldm_get_pdr_resp *response = 37248761c62SAndrew Jeffery (struct pldm_get_pdr_resp *)msg->payload; 37348761c62SAndrew Jeffery response->completion_code = completion_code; 37448761c62SAndrew Jeffery 37548761c62SAndrew Jeffery if (response->completion_code == PLDM_SUCCESS) { 37648761c62SAndrew Jeffery response->next_record_handle = htole32(next_record_hndl); 37748761c62SAndrew Jeffery response->next_data_transfer_handle = 37848761c62SAndrew Jeffery htole32(next_data_transfer_hndl); 37948761c62SAndrew Jeffery response->transfer_flag = transfer_flag; 38048761c62SAndrew Jeffery response->response_count = htole16(resp_cnt); 38148761c62SAndrew Jeffery if (record_data != NULL && resp_cnt > 0) { 38248761c62SAndrew Jeffery memcpy(response->record_data, record_data, resp_cnt); 38348761c62SAndrew Jeffery } 38448761c62SAndrew Jeffery if (transfer_flag == PLDM_END) { 38548761c62SAndrew Jeffery uint8_t *dst = msg->payload; 38648761c62SAndrew Jeffery dst += (sizeof(struct pldm_get_pdr_resp) - 1) + 38748761c62SAndrew Jeffery resp_cnt; 38848761c62SAndrew Jeffery *dst = transfer_crc; 38948761c62SAndrew Jeffery } 39048761c62SAndrew Jeffery } 39148761c62SAndrew Jeffery 39248761c62SAndrew Jeffery return PLDM_SUCCESS; 39348761c62SAndrew Jeffery } 39448761c62SAndrew Jeffery 39548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 39648761c62SAndrew Jeffery int encode_get_pdr_repository_info_resp( 39748761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, uint8_t repository_state, 39848761c62SAndrew Jeffery const uint8_t *update_time, const uint8_t *oem_update_time, 39948761c62SAndrew Jeffery uint32_t record_count, uint32_t repository_size, 40048761c62SAndrew Jeffery uint32_t largest_record_size, uint8_t data_transfer_handle_timeout, 40148761c62SAndrew Jeffery struct pldm_msg *msg) 40248761c62SAndrew Jeffery { 40348761c62SAndrew Jeffery if (msg == NULL) { 40448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 40548761c62SAndrew Jeffery } 40648761c62SAndrew Jeffery 40748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 40848761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 40948761c62SAndrew Jeffery header.instance = instance_id; 41048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 41148761c62SAndrew Jeffery header.command = PLDM_GET_PDR_REPOSITORY_INFO; 41248761c62SAndrew Jeffery 41348761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 41448761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 41548761c62SAndrew Jeffery return rc; 41648761c62SAndrew Jeffery } 41748761c62SAndrew Jeffery 41848761c62SAndrew Jeffery struct pldm_pdr_repository_info_resp *response = 41948761c62SAndrew Jeffery (struct pldm_pdr_repository_info_resp *)msg->payload; 42048761c62SAndrew Jeffery response->completion_code = completion_code; 42148761c62SAndrew Jeffery 42248761c62SAndrew Jeffery if (response->completion_code == PLDM_SUCCESS) { 42348761c62SAndrew Jeffery response->repository_state = repository_state; 42448761c62SAndrew Jeffery if (update_time != NULL) { 42548761c62SAndrew Jeffery memcpy(response->update_time, update_time, 42648761c62SAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 42748761c62SAndrew Jeffery } 42848761c62SAndrew Jeffery if (oem_update_time != NULL) { 42948761c62SAndrew Jeffery memcpy(response->oem_update_time, oem_update_time, 43048761c62SAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 43148761c62SAndrew Jeffery } 43248761c62SAndrew Jeffery response->record_count = htole32(record_count); 43348761c62SAndrew Jeffery response->repository_size = htole32(repository_size); 43448761c62SAndrew Jeffery response->largest_record_size = htole32(largest_record_size); 43548761c62SAndrew Jeffery response->data_transfer_handle_timeout = 43648761c62SAndrew Jeffery data_transfer_handle_timeout; 43748761c62SAndrew Jeffery } 43848761c62SAndrew Jeffery 43948761c62SAndrew Jeffery return PLDM_SUCCESS; 44048761c62SAndrew Jeffery } 44148761c62SAndrew Jeffery 4420a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED 44348761c62SAndrew Jeffery int decode_get_pdr_repository_info_resp( 44448761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 44548761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *repository_state, 44648761c62SAndrew Jeffery uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count, 44748761c62SAndrew Jeffery uint32_t *repository_size, uint32_t *largest_record_size, 44848761c62SAndrew Jeffery uint8_t *data_transfer_handle_timeout) 44948761c62SAndrew Jeffery { 45048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 45148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 45248761c62SAndrew Jeffery int rc; 45348761c62SAndrew Jeffery 45448761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 45548761c62SAndrew Jeffery repository_state == NULL || update_time == NULL || 45648761c62SAndrew Jeffery oem_update_time == NULL || record_count == NULL || 45748761c62SAndrew Jeffery repository_size == NULL || largest_record_size == NULL || 45848761c62SAndrew Jeffery data_transfer_handle_timeout == NULL) { 45948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 46048761c62SAndrew Jeffery } 46148761c62SAndrew Jeffery 462830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 463830c1eb4SAndrew Jeffery PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 46448761c62SAndrew Jeffery msg->payload, payload_length); 46548761c62SAndrew Jeffery if (rc) { 466830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 46748761c62SAndrew Jeffery } 46848761c62SAndrew Jeffery 46948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, completion_code); 47048761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 47148761c62SAndrew Jeffery return PLDM_SUCCESS; 47248761c62SAndrew Jeffery } 47348761c62SAndrew Jeffery 474830c1eb4SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, repository_state); 475830c1eb4SAndrew Jeffery if (rc) { 476830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 477830c1eb4SAndrew Jeffery } 478830c1eb4SAndrew Jeffery 47948761c62SAndrew Jeffery if (*repository_state > PLDM_FAILED) { 48048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 48148761c62SAndrew Jeffery } 48248761c62SAndrew Jeffery 4830a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 4840a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time, 4850a1be3cbSAndrew Jeffery PLDM_TIMESTAMP104_SIZE); 4860a1be3cbSAndrew Jeffery if (rc) { 487830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 4880a1be3cbSAndrew Jeffery } 4890a1be3cbSAndrew Jeffery 4900a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 4910a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, 4920a1be3cbSAndrew Jeffery oem_update_time, PLDM_TIMESTAMP104_SIZE); 4930a1be3cbSAndrew Jeffery if (rc) { 494830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 4950a1be3cbSAndrew Jeffery } 4960a1be3cbSAndrew Jeffery 49748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, record_count); 49848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, repository_size); 49948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, largest_record_size); 50048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout); 50148761c62SAndrew Jeffery 502830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 503830c1eb4SAndrew Jeffery if (rc) { 504830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 505830c1eb4SAndrew Jeffery } 506830c1eb4SAndrew Jeffery 507830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 50848761c62SAndrew Jeffery } 50948761c62SAndrew Jeffery 5100a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING 5110a1be3cbSAndrew Jeffery int decode_get_pdr_repository_info_resp_safe( 5120a1be3cbSAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 5130a1be3cbSAndrew Jeffery struct pldm_pdr_repository_info_resp *resp) 5140a1be3cbSAndrew Jeffery { 5150a1be3cbSAndrew Jeffery struct pldm_msgbuf _buf; 5160a1be3cbSAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 5170a1be3cbSAndrew Jeffery int rc; 5180a1be3cbSAndrew Jeffery 5190a1be3cbSAndrew Jeffery if (msg == NULL || resp == NULL) { 5200a1be3cbSAndrew Jeffery return -EINVAL; 5210a1be3cbSAndrew Jeffery } 5220a1be3cbSAndrew Jeffery 5230a1be3cbSAndrew Jeffery rc = pldm_msg_has_error(msg, payload_length); 5240a1be3cbSAndrew Jeffery if (rc) { 5250a1be3cbSAndrew Jeffery resp->completion_code = rc; 5260a1be3cbSAndrew Jeffery return 0; 5270a1be3cbSAndrew Jeffery } 5280a1be3cbSAndrew Jeffery 5290a1be3cbSAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 5300a1be3cbSAndrew Jeffery PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES, 5310a1be3cbSAndrew Jeffery msg->payload, payload_length); 5320a1be3cbSAndrew Jeffery if (rc) { 5330a1be3cbSAndrew Jeffery return rc; 5340a1be3cbSAndrew Jeffery } 5350a1be3cbSAndrew Jeffery 5360a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->completion_code); 5370a1be3cbSAndrew Jeffery if (rc) { 5380a1be3cbSAndrew Jeffery return rc; 5390a1be3cbSAndrew Jeffery } 5400a1be3cbSAndrew Jeffery 5410a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->repository_state); 5420a1be3cbSAndrew Jeffery 5430a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time), 5440a1be3cbSAndrew Jeffery resp->update_time, 5450a1be3cbSAndrew Jeffery sizeof(resp->update_time)); 5460a1be3cbSAndrew Jeffery if (rc) { 5470a1be3cbSAndrew Jeffery return rc; 5480a1be3cbSAndrew Jeffery } 5490a1be3cbSAndrew Jeffery 5500a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time), 5510a1be3cbSAndrew Jeffery resp->oem_update_time, 5520a1be3cbSAndrew Jeffery sizeof(resp->oem_update_time)); 5530a1be3cbSAndrew Jeffery if (rc) { 5540a1be3cbSAndrew Jeffery return rc; 5550a1be3cbSAndrew Jeffery } 5560a1be3cbSAndrew Jeffery 5570a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->record_count); 5580a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->repository_size); 5590a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->largest_record_size); 5600a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout); 5610a1be3cbSAndrew Jeffery 5620a1be3cbSAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 5630a1be3cbSAndrew Jeffery } 5640a1be3cbSAndrew Jeffery 56548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 56648761c62SAndrew Jeffery int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl, 56748761c62SAndrew Jeffery uint32_t data_transfer_hndl, uint8_t transfer_op_flag, 56848761c62SAndrew Jeffery uint16_t request_cnt, uint16_t record_chg_num, 56948761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 57048761c62SAndrew Jeffery { 57148761c62SAndrew Jeffery if (msg == NULL) { 57248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 57348761c62SAndrew Jeffery } 57448761c62SAndrew Jeffery 57548761c62SAndrew Jeffery if (payload_length != PLDM_GET_PDR_REQ_BYTES) { 57648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 57748761c62SAndrew Jeffery } 57848761c62SAndrew Jeffery 57948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 58048761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 58148761c62SAndrew Jeffery header.instance = instance_id; 58248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 58348761c62SAndrew Jeffery header.command = PLDM_GET_PDR; 58448761c62SAndrew Jeffery 58548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 58648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 58748761c62SAndrew Jeffery return rc; 58848761c62SAndrew Jeffery } 58948761c62SAndrew Jeffery 59048761c62SAndrew Jeffery struct pldm_get_pdr_req *request = 59148761c62SAndrew Jeffery (struct pldm_get_pdr_req *)msg->payload; 59248761c62SAndrew Jeffery request->record_handle = htole32(record_hndl); 59348761c62SAndrew Jeffery request->data_transfer_handle = htole32(data_transfer_hndl); 59448761c62SAndrew Jeffery request->transfer_op_flag = transfer_op_flag; 59548761c62SAndrew Jeffery request->request_count = htole16(request_cnt); 59648761c62SAndrew Jeffery request->record_change_number = htole16(record_chg_num); 59748761c62SAndrew Jeffery 59848761c62SAndrew Jeffery return PLDM_SUCCESS; 59948761c62SAndrew Jeffery } 60048761c62SAndrew Jeffery 6010a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED 60248761c62SAndrew Jeffery int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length, 60348761c62SAndrew Jeffery uint8_t *completion_code, uint32_t *next_record_hndl, 60448761c62SAndrew Jeffery uint32_t *next_data_transfer_hndl, 60548761c62SAndrew Jeffery uint8_t *transfer_flag, uint16_t *resp_cnt, 60648761c62SAndrew Jeffery uint8_t *record_data, size_t record_data_length, 60748761c62SAndrew Jeffery uint8_t *transfer_crc) 60848761c62SAndrew Jeffery { 60948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 61048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 61148761c62SAndrew Jeffery int rc; 61248761c62SAndrew Jeffery 61348761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 61448761c62SAndrew Jeffery next_record_hndl == NULL || next_data_transfer_hndl == NULL || 61548761c62SAndrew Jeffery transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) { 61648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 61748761c62SAndrew Jeffery } 61848761c62SAndrew Jeffery 619830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, 620830c1eb4SAndrew Jeffery msg->payload, payload_length); 62148761c62SAndrew Jeffery if (rc) { 622830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 62348761c62SAndrew Jeffery } 62448761c62SAndrew Jeffery 625830c1eb4SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 626830c1eb4SAndrew Jeffery if (rc) { 627830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 628830c1eb4SAndrew Jeffery } 629830c1eb4SAndrew Jeffery 63048761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 63148761c62SAndrew Jeffery return PLDM_SUCCESS; 63248761c62SAndrew Jeffery } 63348761c62SAndrew Jeffery 63448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_record_hndl); 63548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_data_transfer_hndl); 63648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_flag); 63748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, resp_cnt); 63848761c62SAndrew Jeffery if (rc) { 639830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 64048761c62SAndrew Jeffery } 64148761c62SAndrew Jeffery 64248761c62SAndrew Jeffery if (*resp_cnt > 0 && record_data != NULL) { 64348761c62SAndrew Jeffery if (record_data_length < *resp_cnt) { 64448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 64548761c62SAndrew Jeffery } 6460a1be3cbSAndrew Jeffery /* NOTE: Memory safety */ 6470a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data, 6480a1be3cbSAndrew Jeffery *resp_cnt); 6490a1be3cbSAndrew Jeffery if (rc) { 650830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 6510a1be3cbSAndrew Jeffery } 65248761c62SAndrew Jeffery } 65348761c62SAndrew Jeffery 65448761c62SAndrew Jeffery if (*transfer_flag == PLDM_END) { 65548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_crc); 65648761c62SAndrew Jeffery } 65748761c62SAndrew Jeffery 658830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 659830c1eb4SAndrew Jeffery if (rc) { 660830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 661830c1eb4SAndrew Jeffery } 662830c1eb4SAndrew Jeffery 663830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 66448761c62SAndrew Jeffery } 66548761c62SAndrew Jeffery 6660a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING 6670a1be3cbSAndrew Jeffery int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length, 6680a1be3cbSAndrew Jeffery struct pldm_get_pdr_resp *resp, size_t resp_len, 6690a1be3cbSAndrew Jeffery uint8_t *transfer_crc) 6700a1be3cbSAndrew Jeffery { 6710a1be3cbSAndrew Jeffery struct pldm_msgbuf _buf; 6720a1be3cbSAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 6730a1be3cbSAndrew Jeffery int rc; 6740a1be3cbSAndrew Jeffery 6750a1be3cbSAndrew Jeffery if (msg == NULL || resp == NULL || transfer_crc == NULL) { 6760a1be3cbSAndrew Jeffery return -EINVAL; 6770a1be3cbSAndrew Jeffery } 6780a1be3cbSAndrew Jeffery 6790a1be3cbSAndrew Jeffery rc = pldm_msg_has_error(msg, payload_length); 6800a1be3cbSAndrew Jeffery if (rc) { 6810a1be3cbSAndrew Jeffery resp->completion_code = rc; 6820a1be3cbSAndrew Jeffery return 0; 6830a1be3cbSAndrew Jeffery } 6840a1be3cbSAndrew Jeffery 6850a1be3cbSAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, 6860a1be3cbSAndrew Jeffery msg->payload, payload_length); 6870a1be3cbSAndrew Jeffery if (rc) { 6880a1be3cbSAndrew Jeffery return rc; 6890a1be3cbSAndrew Jeffery } 6900a1be3cbSAndrew Jeffery 6910a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->completion_code); 6920a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->next_record_handle); 6930a1be3cbSAndrew Jeffery pldm_msgbuf_extract(buf, resp->next_data_transfer_handle); 6940a1be3cbSAndrew Jeffery 6950a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->transfer_flag); 6960a1be3cbSAndrew Jeffery if (rc) { 6970a1be3cbSAndrew Jeffery return rc; 6980a1be3cbSAndrew Jeffery } 6990a1be3cbSAndrew Jeffery 7000a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->response_count); 7010a1be3cbSAndrew Jeffery if (rc) { 7020a1be3cbSAndrew Jeffery return rc; 7030a1be3cbSAndrew Jeffery } 7040a1be3cbSAndrew Jeffery 7050a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array( 7060a1be3cbSAndrew Jeffery buf, resp->response_count, resp->record_data, 7070a1be3cbSAndrew Jeffery resp_len - (sizeof(*resp) - sizeof(resp->record_data))); 7080a1be3cbSAndrew Jeffery if (rc) { 7090a1be3cbSAndrew Jeffery return rc; 7100a1be3cbSAndrew Jeffery } 7110a1be3cbSAndrew Jeffery 7120a1be3cbSAndrew Jeffery if (resp->transfer_flag == PLDM_END) { 7130a1be3cbSAndrew Jeffery pldm_msgbuf_extract_p(buf, transfer_crc); 7140a1be3cbSAndrew Jeffery } 7150a1be3cbSAndrew Jeffery 7160a1be3cbSAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 7170a1be3cbSAndrew Jeffery } 7180a1be3cbSAndrew Jeffery 71948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 72048761c62SAndrew Jeffery int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg, 72148761c62SAndrew Jeffery size_t payload_length, 72248761c62SAndrew Jeffery uint16_t *effecter_id, 72348761c62SAndrew Jeffery uint8_t *effecter_data_size, 72448761c62SAndrew Jeffery uint8_t effecter_value[4]) 72548761c62SAndrew Jeffery { 72648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 72748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 72848761c62SAndrew Jeffery int rc; 72948761c62SAndrew Jeffery 73048761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL || 73148761c62SAndrew Jeffery effecter_value == NULL) { 73248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 73348761c62SAndrew Jeffery } 73448761c62SAndrew Jeffery 735830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 736830c1eb4SAndrew Jeffery buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES, 73748761c62SAndrew Jeffery msg->payload, payload_length); 73848761c62SAndrew Jeffery if (rc) { 739830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 74048761c62SAndrew Jeffery } 74148761c62SAndrew Jeffery 74248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 74348761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 74448761c62SAndrew Jeffery if (rc) { 74548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 74648761c62SAndrew Jeffery } 74748761c62SAndrew Jeffery 74848761c62SAndrew Jeffery if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 74948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 75048761c62SAndrew Jeffery } 75148761c62SAndrew Jeffery 75248761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 75348761c62SAndrew Jeffery effecter_value); 75448761c62SAndrew Jeffery 755830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 756830c1eb4SAndrew Jeffery if (rc) { 757830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 758830c1eb4SAndrew Jeffery } 759830c1eb4SAndrew Jeffery 760830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 76148761c62SAndrew Jeffery } 76248761c62SAndrew Jeffery 76348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 76448761c62SAndrew Jeffery int encode_set_numeric_effecter_value_resp(uint8_t instance_id, 76548761c62SAndrew Jeffery uint8_t completion_code, 76648761c62SAndrew Jeffery struct pldm_msg *msg, 76748761c62SAndrew Jeffery size_t payload_length) 76848761c62SAndrew Jeffery { 76948761c62SAndrew Jeffery if (msg == NULL) { 77048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 77148761c62SAndrew Jeffery } 77248761c62SAndrew Jeffery 77348761c62SAndrew Jeffery if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 77448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 77548761c62SAndrew Jeffery } 77648761c62SAndrew Jeffery 77748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 77848761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 77948761c62SAndrew Jeffery header.instance = instance_id; 78048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 78148761c62SAndrew Jeffery header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 78248761c62SAndrew Jeffery 78348761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 78448761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 78548761c62SAndrew Jeffery return rc; 78648761c62SAndrew Jeffery } 78748761c62SAndrew Jeffery 78848761c62SAndrew Jeffery msg->payload[0] = completion_code; 78948761c62SAndrew Jeffery 79048761c62SAndrew Jeffery return rc; 79148761c62SAndrew Jeffery } 79248761c62SAndrew Jeffery 79348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 79448761c62SAndrew Jeffery int encode_set_numeric_effecter_value_req(uint8_t instance_id, 79548761c62SAndrew Jeffery uint16_t effecter_id, 79648761c62SAndrew Jeffery uint8_t effecter_data_size, 79748761c62SAndrew Jeffery const uint8_t *effecter_value, 79848761c62SAndrew Jeffery struct pldm_msg *msg, 79948761c62SAndrew Jeffery size_t payload_length) 80048761c62SAndrew Jeffery { 80148761c62SAndrew Jeffery if (msg == NULL || effecter_value == NULL) { 80248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 80348761c62SAndrew Jeffery } 80448761c62SAndrew Jeffery 80548761c62SAndrew Jeffery if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 80648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 80748761c62SAndrew Jeffery } 80848761c62SAndrew Jeffery 80948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 81048761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 81148761c62SAndrew Jeffery header.instance = instance_id; 81248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 81348761c62SAndrew Jeffery header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE; 81448761c62SAndrew Jeffery 81548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 81648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 81748761c62SAndrew Jeffery return rc; 81848761c62SAndrew Jeffery } 81948761c62SAndrew Jeffery 82048761c62SAndrew Jeffery struct pldm_set_numeric_effecter_value_req *request = 82148761c62SAndrew Jeffery (struct pldm_set_numeric_effecter_value_req *)msg->payload; 82248761c62SAndrew Jeffery if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 82348761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 82448761c62SAndrew Jeffery if (payload_length != 82548761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) { 82648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 82748761c62SAndrew Jeffery } 82848761c62SAndrew Jeffery request->effecter_value[0] = *effecter_value; 82948761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 83048761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 83148761c62SAndrew Jeffery if (payload_length != 83248761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) { 83348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 83448761c62SAndrew Jeffery } 83548761c62SAndrew Jeffery 83648761c62SAndrew Jeffery uint16_t val = *(uint16_t *)(effecter_value); 83748761c62SAndrew Jeffery val = htole16(val); 83848761c62SAndrew Jeffery memcpy(request->effecter_value, &val, sizeof(uint16_t)); 83948761c62SAndrew Jeffery 84048761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 84148761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 84248761c62SAndrew Jeffery if (payload_length != 84348761c62SAndrew Jeffery PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) { 84448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 84548761c62SAndrew Jeffery } 84648761c62SAndrew Jeffery 84748761c62SAndrew Jeffery uint32_t val = *(uint32_t *)(effecter_value); 84848761c62SAndrew Jeffery val = htole32(val); 84948761c62SAndrew Jeffery memcpy(request->effecter_value, &val, sizeof(uint32_t)); 85048761c62SAndrew Jeffery } 85148761c62SAndrew Jeffery 85248761c62SAndrew Jeffery request->effecter_id = htole16(effecter_id); 85348761c62SAndrew Jeffery request->effecter_data_size = effecter_data_size; 85448761c62SAndrew Jeffery 85548761c62SAndrew Jeffery return PLDM_SUCCESS; 85648761c62SAndrew Jeffery } 85748761c62SAndrew Jeffery 85848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 85948761c62SAndrew Jeffery int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg, 86048761c62SAndrew Jeffery size_t payload_length, 86148761c62SAndrew Jeffery uint8_t *completion_code) 86248761c62SAndrew Jeffery { 86348761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 86448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 86548761c62SAndrew Jeffery } 86648761c62SAndrew Jeffery 86748761c62SAndrew Jeffery if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) { 86848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 86948761c62SAndrew Jeffery } 87048761c62SAndrew Jeffery 87148761c62SAndrew Jeffery *completion_code = msg->payload[0]; 87248761c62SAndrew Jeffery 87348761c62SAndrew Jeffery return PLDM_SUCCESS; 87448761c62SAndrew Jeffery } 87548761c62SAndrew Jeffery 87648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 87748761c62SAndrew Jeffery int encode_get_state_sensor_readings_resp(uint8_t instance_id, 87848761c62SAndrew Jeffery uint8_t completion_code, 87948761c62SAndrew Jeffery uint8_t comp_sensor_count, 88048761c62SAndrew Jeffery get_sensor_state_field *field, 88148761c62SAndrew Jeffery struct pldm_msg *msg) 88248761c62SAndrew Jeffery { 88348761c62SAndrew Jeffery if (msg == NULL) { 88448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 88548761c62SAndrew Jeffery } 88648761c62SAndrew Jeffery 88748761c62SAndrew Jeffery if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) { 88848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 88948761c62SAndrew Jeffery } 89048761c62SAndrew Jeffery 89148761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 89248761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 89348761c62SAndrew Jeffery header.instance = instance_id; 89448761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 89548761c62SAndrew Jeffery header.command = PLDM_GET_STATE_SENSOR_READINGS; 89648761c62SAndrew Jeffery 89748761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 89848761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 89948761c62SAndrew Jeffery return rc; 90048761c62SAndrew Jeffery } 90148761c62SAndrew Jeffery 90248761c62SAndrew Jeffery struct pldm_get_state_sensor_readings_resp *response = 90348761c62SAndrew Jeffery (struct pldm_get_state_sensor_readings_resp *)msg->payload; 90448761c62SAndrew Jeffery 90548761c62SAndrew Jeffery response->completion_code = completion_code; 90648761c62SAndrew Jeffery response->comp_sensor_count = comp_sensor_count; 90748761c62SAndrew Jeffery memcpy(response->field, field, 90848761c62SAndrew Jeffery (sizeof(get_sensor_state_field) * comp_sensor_count)); 90948761c62SAndrew Jeffery 91048761c62SAndrew Jeffery return PLDM_SUCCESS; 91148761c62SAndrew Jeffery } 91248761c62SAndrew Jeffery 91348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 91448761c62SAndrew Jeffery int encode_get_state_sensor_readings_req(uint8_t instance_id, 91548761c62SAndrew Jeffery uint16_t sensor_id, 91648761c62SAndrew Jeffery bitfield8_t sensor_rearm, 91748761c62SAndrew Jeffery uint8_t reserved, struct pldm_msg *msg) 91848761c62SAndrew Jeffery { 91948761c62SAndrew Jeffery if (msg == NULL) { 92048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 92148761c62SAndrew Jeffery } 92248761c62SAndrew Jeffery 92348761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 92448761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 92548761c62SAndrew Jeffery header.instance = instance_id; 92648761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 92748761c62SAndrew Jeffery header.command = PLDM_GET_STATE_SENSOR_READINGS; 92848761c62SAndrew Jeffery 92948761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 93048761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 93148761c62SAndrew Jeffery return rc; 93248761c62SAndrew Jeffery } 93348761c62SAndrew Jeffery 93448761c62SAndrew Jeffery struct pldm_get_state_sensor_readings_req *request = 93548761c62SAndrew Jeffery (struct pldm_get_state_sensor_readings_req *)msg->payload; 93648761c62SAndrew Jeffery 93748761c62SAndrew Jeffery request->sensor_id = htole16(sensor_id); 93848761c62SAndrew Jeffery request->reserved = reserved; 93948761c62SAndrew Jeffery request->sensor_rearm = sensor_rearm; 94048761c62SAndrew Jeffery 94148761c62SAndrew Jeffery return PLDM_SUCCESS; 94248761c62SAndrew Jeffery } 94348761c62SAndrew Jeffery 94448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 94548761c62SAndrew Jeffery int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg, 94648761c62SAndrew Jeffery size_t payload_length, 94748761c62SAndrew Jeffery uint8_t *completion_code, 94848761c62SAndrew Jeffery uint8_t *comp_sensor_count, 94948761c62SAndrew Jeffery get_sensor_state_field *field) 95048761c62SAndrew Jeffery { 95148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 95248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 95348761c62SAndrew Jeffery uint8_t i; 95448761c62SAndrew Jeffery int rc; 95548761c62SAndrew Jeffery 95648761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 95748761c62SAndrew Jeffery comp_sensor_count == NULL || field == NULL) { 95848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 95948761c62SAndrew Jeffery } 96048761c62SAndrew Jeffery 961830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 962830c1eb4SAndrew Jeffery buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES, 96348761c62SAndrew Jeffery msg->payload, payload_length); 96448761c62SAndrew Jeffery if (rc) { 965830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 96648761c62SAndrew Jeffery } 96748761c62SAndrew Jeffery 96848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 96948761c62SAndrew Jeffery if (rc) { 970830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 97148761c62SAndrew Jeffery } 97248761c62SAndrew Jeffery 97348761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 97448761c62SAndrew Jeffery return PLDM_SUCCESS; 97548761c62SAndrew Jeffery } 97648761c62SAndrew Jeffery 97748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, comp_sensor_count); 97848761c62SAndrew Jeffery if (rc) { 979830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 98048761c62SAndrew Jeffery } 98148761c62SAndrew Jeffery 98248761c62SAndrew Jeffery if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) { 98348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 98448761c62SAndrew Jeffery } 98548761c62SAndrew Jeffery 98648761c62SAndrew Jeffery for (i = 0; i < *comp_sensor_count; i++) { 98748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].sensor_op_state); 98848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].present_state); 98948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].previous_state); 99048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field[i].event_state); 99148761c62SAndrew Jeffery } 99248761c62SAndrew Jeffery 993830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 994830c1eb4SAndrew Jeffery if (rc) { 995830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 996830c1eb4SAndrew Jeffery } 997830c1eb4SAndrew Jeffery 998830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 99948761c62SAndrew Jeffery } 100048761c62SAndrew Jeffery 100148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 100248761c62SAndrew Jeffery int decode_get_state_sensor_readings_req(const struct pldm_msg *msg, 100348761c62SAndrew Jeffery size_t payload_length, 100448761c62SAndrew Jeffery uint16_t *sensor_id, 100548761c62SAndrew Jeffery bitfield8_t *sensor_rearm, 100648761c62SAndrew Jeffery uint8_t *reserved) 100748761c62SAndrew Jeffery { 100848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 100948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 101048761c62SAndrew Jeffery int rc; 101148761c62SAndrew Jeffery 101248761c62SAndrew Jeffery if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) { 101348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 101448761c62SAndrew Jeffery } 101548761c62SAndrew Jeffery 1016830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 1017830c1eb4SAndrew Jeffery PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES, 101848761c62SAndrew Jeffery msg->payload, payload_length); 101948761c62SAndrew Jeffery if (rc) { 1020830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 102148761c62SAndrew Jeffery } 102248761c62SAndrew Jeffery 102348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 102448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, sensor_rearm->byte); 102548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, reserved); 102648761c62SAndrew Jeffery 1027830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1028830c1eb4SAndrew Jeffery if (rc) { 1029830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1030830c1eb4SAndrew Jeffery } 1031830c1eb4SAndrew Jeffery 1032830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 103348761c62SAndrew Jeffery } 103448761c62SAndrew Jeffery 103548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 103648761c62SAndrew Jeffery int encode_sensor_event_data( 103748761c62SAndrew Jeffery struct pldm_sensor_event_data *const event_data, 103848761c62SAndrew Jeffery const size_t event_data_size, const uint16_t sensor_id, 103948761c62SAndrew Jeffery const enum sensor_event_class_states sensor_event_class, 104048761c62SAndrew Jeffery const uint8_t sensor_offset, const uint8_t event_state, 104148761c62SAndrew Jeffery const uint8_t previous_event_state, 104248761c62SAndrew Jeffery size_t *const actual_event_data_size) 104348761c62SAndrew Jeffery { 104448761c62SAndrew Jeffery *actual_event_data_size = 104548761c62SAndrew Jeffery (sizeof(*event_data) - sizeof(event_data->event_class) + 104648761c62SAndrew Jeffery sizeof(struct pldm_sensor_event_state_sensor_state)); 104748761c62SAndrew Jeffery 104848761c62SAndrew Jeffery if (!event_data) { 104948761c62SAndrew Jeffery return PLDM_SUCCESS; 105048761c62SAndrew Jeffery } 105148761c62SAndrew Jeffery 105248761c62SAndrew Jeffery if (event_data_size < *actual_event_data_size) { 105348761c62SAndrew Jeffery *actual_event_data_size = 0; 105448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 105548761c62SAndrew Jeffery } 105648761c62SAndrew Jeffery 105748761c62SAndrew Jeffery event_data->sensor_id = htole16(sensor_id); 105848761c62SAndrew Jeffery event_data->sensor_event_class_type = sensor_event_class; 105948761c62SAndrew Jeffery 106048761c62SAndrew Jeffery struct pldm_sensor_event_state_sensor_state *const state_data = 106148761c62SAndrew Jeffery (struct pldm_sensor_event_state_sensor_state *) 106248761c62SAndrew Jeffery event_data->event_class; 106348761c62SAndrew Jeffery 106448761c62SAndrew Jeffery state_data->sensor_offset = sensor_offset; 106548761c62SAndrew Jeffery state_data->event_state = event_state; 106648761c62SAndrew Jeffery state_data->previous_event_state = previous_event_state; 106748761c62SAndrew Jeffery 106848761c62SAndrew Jeffery return PLDM_SUCCESS; 106948761c62SAndrew Jeffery } 107048761c62SAndrew Jeffery 107148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 107248761c62SAndrew Jeffery int decode_platform_event_message_req(const struct pldm_msg *msg, 107348761c62SAndrew Jeffery size_t payload_length, 107448761c62SAndrew Jeffery uint8_t *format_version, uint8_t *tid, 107548761c62SAndrew Jeffery uint8_t *event_class, 107648761c62SAndrew Jeffery size_t *event_data_offset) 107748761c62SAndrew Jeffery { 107848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 107948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 108048761c62SAndrew Jeffery int rc; 108148761c62SAndrew Jeffery 108248761c62SAndrew Jeffery if (msg == NULL || format_version == NULL || tid == NULL || 108348761c62SAndrew Jeffery event_class == NULL || event_data_offset == NULL) { 108448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 108548761c62SAndrew Jeffery } 108648761c62SAndrew Jeffery 1087830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 1088830c1eb4SAndrew Jeffery PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES, 108948761c62SAndrew Jeffery msg->payload, payload_length); 109048761c62SAndrew Jeffery if (rc) { 1091830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 109248761c62SAndrew Jeffery } 109348761c62SAndrew Jeffery 109448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, format_version); 109548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, tid); 109648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_class); 1097830c1eb4SAndrew Jeffery 1098830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1099830c1eb4SAndrew Jeffery if (rc) { 1100830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1101830c1eb4SAndrew Jeffery } 1102830c1eb4SAndrew Jeffery 110348761c62SAndrew Jeffery *event_data_offset = 110448761c62SAndrew Jeffery sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class); 110548761c62SAndrew Jeffery 1106830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 110748761c62SAndrew Jeffery } 110848761c62SAndrew Jeffery 1109387b10f6SThu Nguyen static int pldm_platform_poll_for_platform_event_message_validate( 1110387b10f6SThu Nguyen uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge) 1111387b10f6SThu Nguyen { 1112387b10f6SThu Nguyen if (((transfer_operation_flag == PLDM_GET_FIRSTPART) && 1113387b10f6SThu Nguyen (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) || 1114387b10f6SThu Nguyen ((transfer_operation_flag == PLDM_GET_NEXTPART) && 1115387b10f6SThu Nguyen (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 1116387b10f6SThu Nguyen ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 11179e16b18bSThu Nguyen (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) || 11189e16b18bSThu Nguyen ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) && 11199e16b18bSThu Nguyen (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) || 1120387b10f6SThu Nguyen (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) { 1121387b10f6SThu Nguyen return -EPROTO; 1122387b10f6SThu Nguyen } 1123387b10f6SThu Nguyen 1124387b10f6SThu Nguyen return 0; 1125387b10f6SThu Nguyen } 1126387b10f6SThu Nguyen 112748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 112848761c62SAndrew Jeffery int decode_poll_for_platform_event_message_req( 112948761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 113048761c62SAndrew Jeffery uint8_t *format_version, uint8_t *transfer_operation_flag, 113148761c62SAndrew Jeffery uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge) 113248761c62SAndrew Jeffery { 113348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 113448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 113548761c62SAndrew Jeffery int rc; 113648761c62SAndrew Jeffery 113790bbe6c0SAndrew Jeffery if (msg == NULL || format_version == NULL || 113890bbe6c0SAndrew Jeffery transfer_operation_flag == NULL || data_transfer_handle == NULL || 113990bbe6c0SAndrew Jeffery event_id_to_acknowledge == NULL) { 114048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 114148761c62SAndrew Jeffery } 114248761c62SAndrew Jeffery 1143830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 1144830c1eb4SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, 114548761c62SAndrew Jeffery msg->payload, payload_length); 114648761c62SAndrew Jeffery if (rc) { 1147830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 114848761c62SAndrew Jeffery } 114948761c62SAndrew Jeffery 115048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, format_version); 115148761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag); 115248761c62SAndrew Jeffery if (rc) { 1153830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 115448761c62SAndrew Jeffery } 115548761c62SAndrew Jeffery if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) { 115648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 115748761c62SAndrew Jeffery } 115848761c62SAndrew Jeffery 115948761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, data_transfer_handle); 116048761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge); 116148761c62SAndrew Jeffery if (rc) { 1162830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 116348761c62SAndrew Jeffery } 116448761c62SAndrew Jeffery 1165387b10f6SThu Nguyen rc = pldm_platform_poll_for_platform_event_message_validate( 1166387b10f6SThu Nguyen *transfer_operation_flag, *event_id_to_acknowledge); 1167387b10f6SThu Nguyen if (rc < 0) { 116848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 116948761c62SAndrew Jeffery } 117048761c62SAndrew Jeffery 1171830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1172830c1eb4SAndrew Jeffery if (rc) { 1173830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1174830c1eb4SAndrew Jeffery } 1175830c1eb4SAndrew Jeffery 1176830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 117748761c62SAndrew Jeffery } 117848761c62SAndrew Jeffery 117948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 118048761c62SAndrew Jeffery int encode_platform_event_message_resp(uint8_t instance_id, 118148761c62SAndrew Jeffery uint8_t completion_code, 118248761c62SAndrew Jeffery uint8_t platform_event_status, 118348761c62SAndrew Jeffery struct pldm_msg *msg) 118448761c62SAndrew Jeffery { 118548761c62SAndrew Jeffery if (msg == NULL) { 118648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 118748761c62SAndrew Jeffery } 118848761c62SAndrew Jeffery 118948761c62SAndrew Jeffery if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 119048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 119148761c62SAndrew Jeffery } 119248761c62SAndrew Jeffery 119348761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 119448761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 119548761c62SAndrew Jeffery header.instance = instance_id; 119648761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 119748761c62SAndrew Jeffery header.command = PLDM_PLATFORM_EVENT_MESSAGE; 119848761c62SAndrew Jeffery 119948761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 120048761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 120148761c62SAndrew Jeffery return rc; 120248761c62SAndrew Jeffery } 120348761c62SAndrew Jeffery 120448761c62SAndrew Jeffery struct pldm_platform_event_message_resp *response = 120548761c62SAndrew Jeffery (struct pldm_platform_event_message_resp *)msg->payload; 120648761c62SAndrew Jeffery response->completion_code = completion_code; 120748761c62SAndrew Jeffery response->platform_event_status = platform_event_status; 120848761c62SAndrew Jeffery 120948761c62SAndrew Jeffery return PLDM_SUCCESS; 121048761c62SAndrew Jeffery } 121148761c62SAndrew Jeffery 121248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 121348761c62SAndrew Jeffery int encode_poll_for_platform_event_message_resp( 121448761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, uint8_t tid, 121548761c62SAndrew Jeffery uint16_t event_id, uint32_t next_data_transfer_handle, 121648761c62SAndrew Jeffery uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size, 121748761c62SAndrew Jeffery uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg, 121848761c62SAndrew Jeffery size_t payload_length) 121948761c62SAndrew Jeffery { 122048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 122148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 122248761c62SAndrew Jeffery int rc; 122348761c62SAndrew Jeffery 122448761c62SAndrew Jeffery if (!msg) { 122548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 122648761c62SAndrew Jeffery } 122748761c62SAndrew Jeffery 122848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 122948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 123048761c62SAndrew Jeffery header.instance = instance_id; 123148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 123248761c62SAndrew Jeffery header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 123348761c62SAndrew Jeffery 123448761c62SAndrew Jeffery rc = pack_pldm_header(&header, &(msg->hdr)); 123548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 123648761c62SAndrew Jeffery return rc; 123748761c62SAndrew Jeffery } 123848761c62SAndrew Jeffery 1239830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 124048761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 124148761c62SAndrew Jeffery msg->payload, payload_length); 124248761c62SAndrew Jeffery if (rc) { 1243830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 124448761c62SAndrew Jeffery } 124548761c62SAndrew Jeffery 124648761c62SAndrew Jeffery pldm_msgbuf_insert(buf, completion_code); 124748761c62SAndrew Jeffery pldm_msgbuf_insert(buf, tid); 1248830c1eb4SAndrew Jeffery rc = pldm_msgbuf_insert(buf, event_id); 1249830c1eb4SAndrew Jeffery if (rc) { 1250830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1251830c1eb4SAndrew Jeffery } 125248761c62SAndrew Jeffery 125348761c62SAndrew Jeffery if (event_id == 0xffff || event_id == 0x0000) { 125448761c62SAndrew Jeffery if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES != 125548761c62SAndrew Jeffery payload_length) { 125648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 125748761c62SAndrew Jeffery } 1258830c1eb4SAndrew Jeffery 1259830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1260830c1eb4SAndrew Jeffery if (rc) { 1261830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1262830c1eb4SAndrew Jeffery } 1263830c1eb4SAndrew Jeffery 1264830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 126548761c62SAndrew Jeffery } 126648761c62SAndrew Jeffery 126748761c62SAndrew Jeffery if ((event_data == NULL) && (event_data_size > 0)) { 126848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 126948761c62SAndrew Jeffery } 127048761c62SAndrew Jeffery 127148761c62SAndrew Jeffery pldm_msgbuf_insert(buf, next_data_transfer_handle); 127248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, transfer_flag); 127348761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_class); 1274830c1eb4SAndrew Jeffery rc = pldm_msgbuf_insert(buf, event_data_size); 1275830c1eb4SAndrew Jeffery if (rc) { 1276830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1277830c1eb4SAndrew Jeffery } 127848761c62SAndrew Jeffery 127948761c62SAndrew Jeffery if ((event_data_size > 0) && event_data) { 12800a1be3cbSAndrew Jeffery rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data, 12810a1be3cbSAndrew Jeffery event_data_size); 12820a1be3cbSAndrew Jeffery if (rc) { 1283830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 12840a1be3cbSAndrew Jeffery } 128548761c62SAndrew Jeffery } 128648761c62SAndrew Jeffery 128748761c62SAndrew Jeffery if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) { 128848761c62SAndrew Jeffery pldm_msgbuf_insert(buf, checksum); 128948761c62SAndrew Jeffery } 129048761c62SAndrew Jeffery 1291830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1292830c1eb4SAndrew Jeffery if (rc) { 1293830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1294830c1eb4SAndrew Jeffery } 1295830c1eb4SAndrew Jeffery 1296830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 129748761c62SAndrew Jeffery } 129848761c62SAndrew Jeffery 129948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 130048761c62SAndrew Jeffery int encode_platform_event_message_req( 130148761c62SAndrew Jeffery uint8_t instance_id, uint8_t format_version, uint8_t tid, 130248761c62SAndrew Jeffery uint8_t event_class, const uint8_t *event_data, 130348761c62SAndrew Jeffery size_t event_data_length, struct pldm_msg *msg, size_t payload_length) 130448761c62SAndrew Jeffery 130548761c62SAndrew Jeffery { 130648761c62SAndrew Jeffery if (format_version != 1) { 130748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 130848761c62SAndrew Jeffery } 130948761c62SAndrew Jeffery 131048761c62SAndrew Jeffery if (msg == NULL || event_data == NULL) { 131148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 131248761c62SAndrew Jeffery } 131348761c62SAndrew Jeffery 131448761c62SAndrew Jeffery if (event_data_length == 0) { 131548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 131648761c62SAndrew Jeffery } 131748761c62SAndrew Jeffery 1318225530abSAndrew Jeffery if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) < 1319225530abSAndrew Jeffery event_data_length) { 1320225530abSAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 1321225530abSAndrew Jeffery } 1322225530abSAndrew Jeffery 132348761c62SAndrew Jeffery if (payload_length != 132448761c62SAndrew Jeffery PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) { 132548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 132648761c62SAndrew Jeffery } 132748761c62SAndrew Jeffery 1328b43a7787SJohn Chung if (event_class > PLDM_CPER_EVENT && 132948761c62SAndrew Jeffery !(event_class >= 0xf0 && event_class <= 0xfe)) { 133048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 133148761c62SAndrew Jeffery } 133248761c62SAndrew Jeffery 133348761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 133448761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 133548761c62SAndrew Jeffery header.instance = instance_id; 133648761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 133748761c62SAndrew Jeffery header.command = PLDM_PLATFORM_EVENT_MESSAGE; 133848761c62SAndrew Jeffery 133948761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 134048761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 134148761c62SAndrew Jeffery return rc; 134248761c62SAndrew Jeffery } 134348761c62SAndrew Jeffery 134448761c62SAndrew Jeffery struct pldm_platform_event_message_req *request = 134548761c62SAndrew Jeffery (struct pldm_platform_event_message_req *)msg->payload; 134648761c62SAndrew Jeffery request->format_version = format_version; 134748761c62SAndrew Jeffery request->tid = tid; 134848761c62SAndrew Jeffery request->event_class = event_class; 134948761c62SAndrew Jeffery memcpy(request->event_data, event_data, event_data_length); 135048761c62SAndrew Jeffery 135148761c62SAndrew Jeffery return PLDM_SUCCESS; 135248761c62SAndrew Jeffery } 135348761c62SAndrew Jeffery 135448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 135548761c62SAndrew Jeffery int decode_platform_event_message_resp(const struct pldm_msg *msg, 135648761c62SAndrew Jeffery size_t payload_length, 135748761c62SAndrew Jeffery uint8_t *completion_code, 135848761c62SAndrew Jeffery uint8_t *platform_event_status) 135948761c62SAndrew Jeffery { 136048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 136148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 136248761c62SAndrew Jeffery int rc; 136348761c62SAndrew Jeffery 136448761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 136548761c62SAndrew Jeffery platform_event_status == NULL) { 136648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 136748761c62SAndrew Jeffery } 136848761c62SAndrew Jeffery 1369830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 137048761c62SAndrew Jeffery msg->payload, payload_length); 137148761c62SAndrew Jeffery if (rc) { 1372830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 137348761c62SAndrew Jeffery } 137448761c62SAndrew Jeffery 137548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 137648761c62SAndrew Jeffery if (rc) { 1377830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 137848761c62SAndrew Jeffery } 137948761c62SAndrew Jeffery 138048761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 138148761c62SAndrew Jeffery return PLDM_SUCCESS; 138248761c62SAndrew Jeffery } 138348761c62SAndrew Jeffery 138448761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, platform_event_status); 138548761c62SAndrew Jeffery if (rc) { 1386830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 138748761c62SAndrew Jeffery } 138848761c62SAndrew Jeffery 138948761c62SAndrew Jeffery if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) { 139048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 139148761c62SAndrew Jeffery } 139248761c62SAndrew Jeffery 1393830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1394830c1eb4SAndrew Jeffery if (rc) { 1395830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1396830c1eb4SAndrew Jeffery } 1397830c1eb4SAndrew Jeffery 1398830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 139948761c62SAndrew Jeffery } 140048761c62SAndrew Jeffery 140148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 140248761c62SAndrew Jeffery int encode_event_message_buffer_size_req(uint8_t instance_id, 140348761c62SAndrew Jeffery uint16_t event_receiver_max_buffer_size, 140448761c62SAndrew Jeffery struct pldm_msg *msg) 140548761c62SAndrew Jeffery { 140648761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 140748761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 140848761c62SAndrew Jeffery header.instance = instance_id; 140948761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 141048761c62SAndrew Jeffery header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE; 141148761c62SAndrew Jeffery 141248761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 141348761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 141448761c62SAndrew Jeffery return rc; 141548761c62SAndrew Jeffery } 141648761c62SAndrew Jeffery 141748761c62SAndrew Jeffery struct pldm_event_message_buffer_size_req *request = 141848761c62SAndrew Jeffery (struct pldm_event_message_buffer_size_req *)msg->payload; 141948761c62SAndrew Jeffery request->event_receiver_max_buffer_size = 142048761c62SAndrew Jeffery event_receiver_max_buffer_size; 142148761c62SAndrew Jeffery 142248761c62SAndrew Jeffery return PLDM_SUCCESS; 142348761c62SAndrew Jeffery } 142448761c62SAndrew Jeffery 142548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 142648761c62SAndrew Jeffery int decode_event_message_buffer_size_resp(const struct pldm_msg *msg, 142748761c62SAndrew Jeffery size_t payload_length, 142848761c62SAndrew Jeffery uint8_t *completion_code, 142948761c62SAndrew Jeffery uint16_t *terminus_max_buffer_size) 143048761c62SAndrew Jeffery { 143148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 143248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 143348761c62SAndrew Jeffery int rc; 143448761c62SAndrew Jeffery 143548761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 143648761c62SAndrew Jeffery terminus_max_buffer_size == NULL) { 143748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 143848761c62SAndrew Jeffery } 143948761c62SAndrew Jeffery 1440830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 1441830c1eb4SAndrew Jeffery PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES, 144248761c62SAndrew Jeffery msg->payload, payload_length); 144348761c62SAndrew Jeffery if (rc) { 1444830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 144548761c62SAndrew Jeffery } 144648761c62SAndrew Jeffery 144748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 144848761c62SAndrew Jeffery if (rc) { 1449830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 145048761c62SAndrew Jeffery } 145148761c62SAndrew Jeffery 145248761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 145348761c62SAndrew Jeffery return PLDM_SUCCESS; 145448761c62SAndrew Jeffery } 145548761c62SAndrew Jeffery 145648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, terminus_max_buffer_size); 145748761c62SAndrew Jeffery 1458830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1459830c1eb4SAndrew Jeffery if (rc) { 1460830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1461830c1eb4SAndrew Jeffery } 1462830c1eb4SAndrew Jeffery 1463830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 146448761c62SAndrew Jeffery } 146548761c62SAndrew Jeffery 146648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 146748761c62SAndrew Jeffery int encode_event_message_supported_req(uint8_t instance_id, 146848761c62SAndrew Jeffery uint8_t format_version, 146948761c62SAndrew Jeffery struct pldm_msg *msg) 147048761c62SAndrew Jeffery { 147148761c62SAndrew Jeffery if (format_version != 1) { 147248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 147348761c62SAndrew Jeffery } 147448761c62SAndrew Jeffery 147548761c62SAndrew Jeffery if (msg == NULL) { 147648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 147748761c62SAndrew Jeffery } 147848761c62SAndrew Jeffery 147948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 148048761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 148148761c62SAndrew Jeffery header.instance = instance_id; 148248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 148348761c62SAndrew Jeffery header.command = PLDM_EVENT_MESSAGE_SUPPORTED; 148448761c62SAndrew Jeffery 148548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 148648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 148748761c62SAndrew Jeffery return rc; 148848761c62SAndrew Jeffery } 148948761c62SAndrew Jeffery 149048761c62SAndrew Jeffery struct pldm_event_message_supported_req *request = 149148761c62SAndrew Jeffery (struct pldm_event_message_supported_req *)msg->payload; 149248761c62SAndrew Jeffery request->format_version = format_version; 149348761c62SAndrew Jeffery 149448761c62SAndrew Jeffery return PLDM_SUCCESS; 149548761c62SAndrew Jeffery } 149648761c62SAndrew Jeffery 149748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 149848761c62SAndrew Jeffery int decode_event_message_supported_resp(const struct pldm_msg *msg, 149948761c62SAndrew Jeffery size_t payload_length, 150048761c62SAndrew Jeffery uint8_t *completion_code, 150148761c62SAndrew Jeffery uint8_t *synchrony_config, 150248761c62SAndrew Jeffery bitfield8_t *synchrony_config_support, 150348761c62SAndrew Jeffery uint8_t *number_event_class_returned, 150448761c62SAndrew Jeffery uint8_t *event_class, 150548761c62SAndrew Jeffery uint8_t event_class_count) 150648761c62SAndrew Jeffery { 150748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 150848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 150948761c62SAndrew Jeffery int i; 151048761c62SAndrew Jeffery int rc; 151148761c62SAndrew Jeffery 151248761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 151348761c62SAndrew Jeffery synchrony_config == NULL || synchrony_config_support == NULL || 151448761c62SAndrew Jeffery number_event_class_returned == NULL || event_class == NULL) { 151548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 151648761c62SAndrew Jeffery } 151748761c62SAndrew Jeffery 1518830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 151948761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES, 152048761c62SAndrew Jeffery msg->payload, payload_length); 152148761c62SAndrew Jeffery if (rc) { 1522830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 152348761c62SAndrew Jeffery } 152448761c62SAndrew Jeffery 152548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 152648761c62SAndrew Jeffery if (rc) { 1527830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 152848761c62SAndrew Jeffery } 152948761c62SAndrew Jeffery 153048761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 153148761c62SAndrew Jeffery return PLDM_SUCCESS; 153248761c62SAndrew Jeffery } 153348761c62SAndrew Jeffery 153448761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, synchrony_config); 153548761c62SAndrew Jeffery if (rc) { 1536830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 153748761c62SAndrew Jeffery } 153848761c62SAndrew Jeffery 153948761c62SAndrew Jeffery if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) { 154048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 154148761c62SAndrew Jeffery } 154248761c62SAndrew Jeffery 154348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte); 154448761c62SAndrew Jeffery 154548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, number_event_class_returned); 154648761c62SAndrew Jeffery if (rc) { 1547830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 154848761c62SAndrew Jeffery } 154948761c62SAndrew Jeffery 155048761c62SAndrew Jeffery if (*number_event_class_returned == 0) { 1551830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1552830c1eb4SAndrew Jeffery if (rc) { 1553830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1554830c1eb4SAndrew Jeffery } 1555830c1eb4SAndrew Jeffery 1556830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 155748761c62SAndrew Jeffery } 155848761c62SAndrew Jeffery 155948761c62SAndrew Jeffery if (event_class_count < *number_event_class_returned) { 156048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 156148761c62SAndrew Jeffery } 156248761c62SAndrew Jeffery 156348761c62SAndrew Jeffery for (i = 0; i < *number_event_class_returned; i++) { 156448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, event_class[i]); 156548761c62SAndrew Jeffery } 156648761c62SAndrew Jeffery 1567830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1568830c1eb4SAndrew Jeffery if (rc) { 1569830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1570830c1eb4SAndrew Jeffery } 1571830c1eb4SAndrew Jeffery 1572830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 157348761c62SAndrew Jeffery } 157448761c62SAndrew Jeffery 157548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 157648761c62SAndrew Jeffery int decode_sensor_event_data(const uint8_t *event_data, 157748761c62SAndrew Jeffery size_t event_data_length, uint16_t *sensor_id, 157848761c62SAndrew Jeffery uint8_t *sensor_event_class_type, 157948761c62SAndrew Jeffery size_t *event_class_data_offset) 158048761c62SAndrew Jeffery { 158148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 158248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 158348761c62SAndrew Jeffery int rc; 158448761c62SAndrew Jeffery 158590bbe6c0SAndrew Jeffery if (event_data == NULL || sensor_id == NULL || 158690bbe6c0SAndrew Jeffery sensor_event_class_type == NULL || 158790bbe6c0SAndrew Jeffery event_class_data_offset == NULL) { 158890bbe6c0SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 158990bbe6c0SAndrew Jeffery } 159090bbe6c0SAndrew Jeffery 1591830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH, 159248761c62SAndrew Jeffery event_data, event_data_length); 159348761c62SAndrew Jeffery if (rc) { 1594830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1595830c1eb4SAndrew Jeffery } 1596830c1eb4SAndrew Jeffery 1597830c1eb4SAndrew Jeffery if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) { 1598830c1eb4SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 159948761c62SAndrew Jeffery } 160048761c62SAndrew Jeffery 160148761c62SAndrew Jeffery size_t event_class_data_length = 160248761c62SAndrew Jeffery event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES; 160348761c62SAndrew Jeffery 160448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 160548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type); 160648761c62SAndrew Jeffery if (rc) { 1607830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 160848761c62SAndrew Jeffery } 160948761c62SAndrew Jeffery 161048761c62SAndrew Jeffery if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) { 161148761c62SAndrew Jeffery if (event_class_data_length != 161248761c62SAndrew Jeffery PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) { 161348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 161448761c62SAndrew Jeffery } 161548761c62SAndrew Jeffery } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) { 161648761c62SAndrew Jeffery if (event_class_data_length != 161748761c62SAndrew Jeffery PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) { 161848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 161948761c62SAndrew Jeffery } 162048761c62SAndrew Jeffery } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) { 162148761c62SAndrew Jeffery if (event_class_data_length < 162248761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH || 162348761c62SAndrew Jeffery event_class_data_length > 162448761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 162548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 162648761c62SAndrew Jeffery } 162748761c62SAndrew Jeffery } else { 162848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 162948761c62SAndrew Jeffery } 163048761c62SAndrew Jeffery 163148761c62SAndrew Jeffery *event_class_data_offset = 163248761c62SAndrew Jeffery sizeof(*sensor_id) + sizeof(*sensor_event_class_type); 163348761c62SAndrew Jeffery 1634830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1635830c1eb4SAndrew Jeffery if (rc) { 1636830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1637830c1eb4SAndrew Jeffery } 1638830c1eb4SAndrew Jeffery 1639830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 164048761c62SAndrew Jeffery } 164148761c62SAndrew Jeffery 164248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 164348761c62SAndrew Jeffery int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length, 164448761c62SAndrew Jeffery uint8_t *present_op_state, uint8_t *previous_op_state) 164548761c62SAndrew Jeffery { 164648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 164748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 164848761c62SAndrew Jeffery int rc; 164948761c62SAndrew Jeffery 165090bbe6c0SAndrew Jeffery if (sensor_data == NULL || present_op_state == NULL || 165190bbe6c0SAndrew Jeffery previous_op_state == NULL) { 165248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 165348761c62SAndrew Jeffery } 165448761c62SAndrew Jeffery 1655830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 1656830c1eb4SAndrew Jeffery buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data, 1657830c1eb4SAndrew Jeffery sensor_data_length); 165848761c62SAndrew Jeffery if (rc) { 1659830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 166048761c62SAndrew Jeffery } 166148761c62SAndrew Jeffery 166248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, present_op_state); 166348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_op_state); 166448761c62SAndrew Jeffery 1665830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1666830c1eb4SAndrew Jeffery if (rc) { 1667830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1668830c1eb4SAndrew Jeffery } 1669830c1eb4SAndrew Jeffery 1670830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 167148761c62SAndrew Jeffery } 167248761c62SAndrew Jeffery 167348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 167448761c62SAndrew Jeffery int decode_state_sensor_data(const uint8_t *sensor_data, 167548761c62SAndrew Jeffery size_t sensor_data_length, uint8_t *sensor_offset, 167648761c62SAndrew Jeffery uint8_t *event_state, 167748761c62SAndrew Jeffery uint8_t *previous_event_state) 167848761c62SAndrew Jeffery { 167948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 168048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 168148761c62SAndrew Jeffery int rc; 168248761c62SAndrew Jeffery 168390bbe6c0SAndrew Jeffery if (sensor_data == NULL || sensor_offset == NULL || 168490bbe6c0SAndrew Jeffery event_state == NULL || previous_event_state == NULL) { 168548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 168648761c62SAndrew Jeffery } 168748761c62SAndrew Jeffery 1688830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 168948761c62SAndrew Jeffery buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH, 169048761c62SAndrew Jeffery sensor_data, sensor_data_length); 169148761c62SAndrew Jeffery if (rc) { 1692830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 169348761c62SAndrew Jeffery } 169448761c62SAndrew Jeffery 169548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_offset); 169648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 169748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_event_state); 169848761c62SAndrew Jeffery 1699830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1700830c1eb4SAndrew Jeffery if (rc) { 1701830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1702830c1eb4SAndrew Jeffery } 1703830c1eb4SAndrew Jeffery 1704830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 170548761c62SAndrew Jeffery } 170648761c62SAndrew Jeffery 170748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 170848761c62SAndrew Jeffery int decode_numeric_sensor_data(const uint8_t *sensor_data, 170948761c62SAndrew Jeffery size_t sensor_data_length, uint8_t *event_state, 171048761c62SAndrew Jeffery uint8_t *previous_event_state, 171148761c62SAndrew Jeffery uint8_t *sensor_data_size, 171248761c62SAndrew Jeffery uint32_t *present_reading) 171348761c62SAndrew Jeffery { 171448761c62SAndrew Jeffery struct pldm_msgbuf _buf; 171548761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 171648761c62SAndrew Jeffery int rc; 171748761c62SAndrew Jeffery 171890bbe6c0SAndrew Jeffery if (sensor_data == NULL || sensor_data_size == NULL || 171990bbe6c0SAndrew Jeffery event_state == NULL || previous_event_state == NULL || 172090bbe6c0SAndrew Jeffery present_reading == NULL) { 172148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 172248761c62SAndrew Jeffery } 172348761c62SAndrew Jeffery 172448761c62SAndrew Jeffery if (sensor_data_length > 172548761c62SAndrew Jeffery PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) { 172648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 172748761c62SAndrew Jeffery } 172848761c62SAndrew Jeffery 1729830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 173048761c62SAndrew Jeffery buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH, 173148761c62SAndrew Jeffery sensor_data, sensor_data_length); 173248761c62SAndrew Jeffery if (rc) { 1733830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 173448761c62SAndrew Jeffery } 173548761c62SAndrew Jeffery 173648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 173748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_event_state); 173848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 173948761c62SAndrew Jeffery if (rc) { 1740830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 174148761c62SAndrew Jeffery } 174248761c62SAndrew Jeffery 174348761c62SAndrew Jeffery /* 174448761c62SAndrew Jeffery * The implementation below is bonkers, but it's because the function 174548761c62SAndrew Jeffery * prototype is bonkers. The `present_reading` argument should have been 174648761c62SAndrew Jeffery * a tagged union. 174748761c62SAndrew Jeffery */ 174848761c62SAndrew Jeffery switch (*sensor_data_size) { 174948761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT8: { 175048761c62SAndrew Jeffery uint8_t val; 175148761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 175248761c62SAndrew Jeffery *present_reading = (uint32_t)val; 175348761c62SAndrew Jeffery } 175448761c62SAndrew Jeffery break; 175548761c62SAndrew Jeffery } 175648761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT8: { 175748761c62SAndrew Jeffery int8_t val; 175848761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 175948761c62SAndrew Jeffery *present_reading = (uint32_t)(int32_t)val; 176048761c62SAndrew Jeffery } 176148761c62SAndrew Jeffery break; 176248761c62SAndrew Jeffery } 176348761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT16: { 176448761c62SAndrew Jeffery uint16_t val; 176548761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 176648761c62SAndrew Jeffery *present_reading = (uint32_t)val; 176748761c62SAndrew Jeffery } 176848761c62SAndrew Jeffery break; 176948761c62SAndrew Jeffery } 177048761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT16: { 177148761c62SAndrew Jeffery int16_t val; 177248761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 177348761c62SAndrew Jeffery *present_reading = (uint32_t)(int32_t)val; 177448761c62SAndrew Jeffery } 177548761c62SAndrew Jeffery break; 177648761c62SAndrew Jeffery } 177748761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_UINT32: { 177848761c62SAndrew Jeffery uint32_t val; 177948761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 178048761c62SAndrew Jeffery *present_reading = (uint32_t)val; 178148761c62SAndrew Jeffery } 178248761c62SAndrew Jeffery break; 178348761c62SAndrew Jeffery } 178448761c62SAndrew Jeffery case PLDM_SENSOR_DATA_SIZE_SINT32: { 178548761c62SAndrew Jeffery int32_t val; 178648761c62SAndrew Jeffery if (!pldm_msgbuf_extract(buf, val)) { 178748761c62SAndrew Jeffery *present_reading = (uint32_t)val; 178848761c62SAndrew Jeffery } 178948761c62SAndrew Jeffery break; 179048761c62SAndrew Jeffery } 179148761c62SAndrew Jeffery default: 179248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 179348761c62SAndrew Jeffery } 179448761c62SAndrew Jeffery 1795830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 1796830c1eb4SAndrew Jeffery if (rc) { 1797830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1798830c1eb4SAndrew Jeffery } 1799830c1eb4SAndrew Jeffery 1800830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 180148761c62SAndrew Jeffery } 180248761c62SAndrew Jeffery 180348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 180448761c62SAndrew Jeffery int decode_numeric_sensor_pdr_data( 180548761c62SAndrew Jeffery const void *pdr_data, size_t pdr_data_length, 180648761c62SAndrew Jeffery struct pldm_numeric_sensor_value_pdr *pdr_value) 180748761c62SAndrew Jeffery { 180848761c62SAndrew Jeffery struct pldm_msgbuf _buf; 180948761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 181048761c62SAndrew Jeffery int rc; 181148761c62SAndrew Jeffery 1812830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 181348761c62SAndrew Jeffery pdr_data, pdr_data_length); 181448761c62SAndrew Jeffery if (rc) { 1815830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 181648761c62SAndrew Jeffery } 181748761c62SAndrew Jeffery 1818329176a8SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr( 1819329176a8SAndrew Jeffery buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 182048761c62SAndrew Jeffery pdr_data_length); 182148761c62SAndrew Jeffery if (rc) { 1822329176a8SAndrew Jeffery return pldm_xlate_errno(rc); 182348761c62SAndrew Jeffery } 182448761c62SAndrew Jeffery 182548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 182648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_id); 182748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_type); 182848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_instance_num); 182948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->container_id); 183048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_init); 183148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr); 183248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_unit); 183348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 183448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rate_unit); 183548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 183648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit); 183748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 183848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 183948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rel); 184048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 184148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->is_linear); 184248761c62SAndrew Jeffery 184348761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size); 184448761c62SAndrew Jeffery if (rc) { 1845830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 184648761c62SAndrew Jeffery } 184748761c62SAndrew Jeffery if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 184848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 184948761c62SAndrew Jeffery } 185048761c62SAndrew Jeffery 185148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->resolution); 185248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->offset); 185348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->accuracy); 185448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 185548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 185648761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 185748761c62SAndrew Jeffery &pdr_value->hysteresis); 185848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte); 185948761c62SAndrew Jeffery pldm_msgbuf_extract( 186048761c62SAndrew Jeffery buf, pdr_value->threshold_and_hysteresis_volatility.byte); 186148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 186248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->update_interval); 186348761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 186448761c62SAndrew Jeffery &pdr_value->max_readable); 186548761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size, 186648761c62SAndrew Jeffery &pdr_value->min_readable); 186748761c62SAndrew Jeffery 186848761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 186948761c62SAndrew Jeffery if (rc) { 1870830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 187148761c62SAndrew Jeffery } 187248761c62SAndrew Jeffery if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 187348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 187448761c62SAndrew Jeffery } 187548761c62SAndrew Jeffery 187648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 187748761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 187848761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->nominal_value); 187948761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 188048761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_max); 188148761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 188248761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_min); 188348761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 188448761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->warning_high); 188548761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 188648761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->warning_low); 188748761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 188848761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->critical_high); 188948761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 189048761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->critical_low); 189148761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 189248761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->fatal_high); 189348761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 189448761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->fatal_low); 189548761c62SAndrew Jeffery 1896830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 1897830c1eb4SAndrew Jeffery if (rc) { 1898830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 1899830c1eb4SAndrew Jeffery } 1900830c1eb4SAndrew Jeffery 1901830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 190248761c62SAndrew Jeffery } 190348761c62SAndrew Jeffery 190448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 190548761c62SAndrew Jeffery int encode_get_numeric_effecter_value_req(uint8_t instance_id, 190648761c62SAndrew Jeffery uint16_t effecter_id, 190748761c62SAndrew Jeffery struct pldm_msg *msg) 190848761c62SAndrew Jeffery { 190948761c62SAndrew Jeffery if (msg == NULL) { 191048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 191148761c62SAndrew Jeffery } 191248761c62SAndrew Jeffery 191348761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 191448761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 191548761c62SAndrew Jeffery header.instance = instance_id; 191648761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 191748761c62SAndrew Jeffery header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 191848761c62SAndrew Jeffery 191948761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 192048761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 192148761c62SAndrew Jeffery return rc; 192248761c62SAndrew Jeffery } 192348761c62SAndrew Jeffery 192448761c62SAndrew Jeffery struct pldm_get_numeric_effecter_value_req *request = 192548761c62SAndrew Jeffery (struct pldm_get_numeric_effecter_value_req *)msg->payload; 192648761c62SAndrew Jeffery request->effecter_id = htole16(effecter_id); 192748761c62SAndrew Jeffery 192848761c62SAndrew Jeffery return PLDM_SUCCESS; 192948761c62SAndrew Jeffery } 193048761c62SAndrew Jeffery 193148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 193248761c62SAndrew Jeffery int encode_get_numeric_effecter_value_resp( 193348761c62SAndrew Jeffery uint8_t instance_id, uint8_t completion_code, 193448761c62SAndrew Jeffery uint8_t effecter_data_size, uint8_t effecter_oper_state, 193548761c62SAndrew Jeffery const uint8_t *pending_value, const uint8_t *present_value, 193648761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 193748761c62SAndrew Jeffery { 193848761c62SAndrew Jeffery if (msg == NULL || pending_value == NULL || present_value == NULL) { 193948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 194048761c62SAndrew Jeffery } 194148761c62SAndrew Jeffery 194248761c62SAndrew Jeffery if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 194348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 194448761c62SAndrew Jeffery } 194548761c62SAndrew Jeffery 194648761c62SAndrew Jeffery if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 194748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 194848761c62SAndrew Jeffery } 194948761c62SAndrew Jeffery 195048761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 195148761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 195248761c62SAndrew Jeffery header.instance = instance_id; 195348761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 195448761c62SAndrew Jeffery header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE; 195548761c62SAndrew Jeffery 195648761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 195748761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 195848761c62SAndrew Jeffery return rc; 195948761c62SAndrew Jeffery } 196048761c62SAndrew Jeffery 196148761c62SAndrew Jeffery struct pldm_get_numeric_effecter_value_resp *response = 196248761c62SAndrew Jeffery (struct pldm_get_numeric_effecter_value_resp *)msg->payload; 196348761c62SAndrew Jeffery 196448761c62SAndrew Jeffery response->completion_code = completion_code; 196548761c62SAndrew Jeffery response->effecter_data_size = effecter_data_size; 196648761c62SAndrew Jeffery response->effecter_oper_state = effecter_oper_state; 196748761c62SAndrew Jeffery 196848761c62SAndrew Jeffery if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 196948761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 197048761c62SAndrew Jeffery if (payload_length != 197148761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) { 197248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 197348761c62SAndrew Jeffery } 197448761c62SAndrew Jeffery response->pending_and_present_values[0] = *pending_value; 197548761c62SAndrew Jeffery response->pending_and_present_values[1] = *present_value; 197648761c62SAndrew Jeffery 197748761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 197848761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 197948761c62SAndrew Jeffery if (payload_length != 198048761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) { 198148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 198248761c62SAndrew Jeffery } 198348761c62SAndrew Jeffery uint16_t val_pending = *(uint16_t *)pending_value; 198448761c62SAndrew Jeffery val_pending = htole16(val_pending); 198548761c62SAndrew Jeffery memcpy(response->pending_and_present_values, &val_pending, 198648761c62SAndrew Jeffery sizeof(uint16_t)); 198748761c62SAndrew Jeffery uint16_t val_present = *(uint16_t *)present_value; 198848761c62SAndrew Jeffery val_present = htole16(val_present); 198948761c62SAndrew Jeffery memcpy((response->pending_and_present_values + 199048761c62SAndrew Jeffery sizeof(uint16_t)), 199148761c62SAndrew Jeffery &val_present, sizeof(uint16_t)); 199248761c62SAndrew Jeffery 199348761c62SAndrew Jeffery } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 199448761c62SAndrew Jeffery effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 199548761c62SAndrew Jeffery if (payload_length != 199648761c62SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) { 199748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 199848761c62SAndrew Jeffery } 199948761c62SAndrew Jeffery uint32_t val_pending = *(uint32_t *)pending_value; 200048761c62SAndrew Jeffery val_pending = htole32(val_pending); 200148761c62SAndrew Jeffery memcpy(response->pending_and_present_values, &val_pending, 200248761c62SAndrew Jeffery sizeof(uint32_t)); 200348761c62SAndrew Jeffery uint32_t val_present = *(uint32_t *)present_value; 200448761c62SAndrew Jeffery val_present = htole32(val_present); 200548761c62SAndrew Jeffery memcpy((response->pending_and_present_values + 200648761c62SAndrew Jeffery sizeof(uint32_t)), 200748761c62SAndrew Jeffery &val_present, sizeof(uint32_t)); 200848761c62SAndrew Jeffery } 200948761c62SAndrew Jeffery return PLDM_SUCCESS; 201048761c62SAndrew Jeffery } 201148761c62SAndrew Jeffery 201248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 201348761c62SAndrew Jeffery int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg, 201448761c62SAndrew Jeffery size_t payload_length, 201548761c62SAndrew Jeffery uint16_t *effecter_id) 201648761c62SAndrew Jeffery { 201748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 201848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 201948761c62SAndrew Jeffery int rc; 202048761c62SAndrew Jeffery 202148761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL) { 202248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 202348761c62SAndrew Jeffery } 202448761c62SAndrew Jeffery 2025830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 2026830c1eb4SAndrew Jeffery PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES, 202748761c62SAndrew Jeffery msg->payload, payload_length); 202848761c62SAndrew Jeffery if (rc) { 2029830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 203048761c62SAndrew Jeffery } 203148761c62SAndrew Jeffery 203248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 203348761c62SAndrew Jeffery 2034830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2035830c1eb4SAndrew Jeffery if (rc) { 2036830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2037830c1eb4SAndrew Jeffery } 2038830c1eb4SAndrew Jeffery 2039830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 204048761c62SAndrew Jeffery } 204148761c62SAndrew Jeffery 204248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 204348761c62SAndrew Jeffery int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg, 204448761c62SAndrew Jeffery size_t payload_length, 204548761c62SAndrew Jeffery uint8_t *completion_code, 204648761c62SAndrew Jeffery uint8_t *effecter_data_size, 204748761c62SAndrew Jeffery uint8_t *effecter_oper_state, 204848761c62SAndrew Jeffery uint8_t *pending_value, 204948761c62SAndrew Jeffery uint8_t *present_value) 205048761c62SAndrew Jeffery { 205148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 205248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 205348761c62SAndrew Jeffery int rc; 205448761c62SAndrew Jeffery 205548761c62SAndrew Jeffery if (msg == NULL || effecter_data_size == NULL || 205648761c62SAndrew Jeffery effecter_oper_state == NULL || pending_value == NULL || 205748761c62SAndrew Jeffery present_value == NULL) { 205848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 205948761c62SAndrew Jeffery } 206048761c62SAndrew Jeffery 2061830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 2062830c1eb4SAndrew Jeffery buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES, 206348761c62SAndrew Jeffery msg->payload, payload_length); 206448761c62SAndrew Jeffery if (rc) { 2065830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 206648761c62SAndrew Jeffery } 206748761c62SAndrew Jeffery 206848761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 206948761c62SAndrew Jeffery if (rc) { 2070830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 207148761c62SAndrew Jeffery } 207248761c62SAndrew Jeffery 207348761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 207448761c62SAndrew Jeffery return PLDM_SUCCESS; 207548761c62SAndrew Jeffery } 207648761c62SAndrew Jeffery 207748761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_data_size); 207848761c62SAndrew Jeffery if (rc) { 2079830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 208048761c62SAndrew Jeffery } 208148761c62SAndrew Jeffery 208248761c62SAndrew Jeffery if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 208348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 208448761c62SAndrew Jeffery } 208548761c62SAndrew Jeffery 208648761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, effecter_oper_state); 208748761c62SAndrew Jeffery if (rc) { 2088830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 208948761c62SAndrew Jeffery } 209048761c62SAndrew Jeffery 209148761c62SAndrew Jeffery if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) { 209248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 209348761c62SAndrew Jeffery } 209448761c62SAndrew Jeffery 209548761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 209648761c62SAndrew Jeffery pending_value); 209748761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size, 209848761c62SAndrew Jeffery present_value); 209948761c62SAndrew Jeffery 2100830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2101830c1eb4SAndrew Jeffery if (rc) { 2102830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2103830c1eb4SAndrew Jeffery } 2104830c1eb4SAndrew Jeffery 2105830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 210648761c62SAndrew Jeffery } 210748761c62SAndrew Jeffery 210848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 210948761c62SAndrew Jeffery int encode_pldm_pdr_repository_chg_event_data( 211048761c62SAndrew Jeffery uint8_t event_data_format, uint8_t number_of_change_records, 211148761c62SAndrew Jeffery const uint8_t *event_data_operations, 211248761c62SAndrew Jeffery const uint8_t *numbers_of_change_entries, 211348761c62SAndrew Jeffery const uint32_t *const *change_entries, 211448761c62SAndrew Jeffery struct pldm_pdr_repository_chg_event_data *event_data, 211548761c62SAndrew Jeffery size_t *actual_change_records_size, size_t max_change_records_size) 211648761c62SAndrew Jeffery { 211748761c62SAndrew Jeffery if (event_data_operations == NULL || 211848761c62SAndrew Jeffery numbers_of_change_entries == NULL || change_entries == NULL) { 211948761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 212048761c62SAndrew Jeffery } 212148761c62SAndrew Jeffery 212248761c62SAndrew Jeffery size_t expected_size = 212348761c62SAndrew Jeffery sizeof(event_data_format) + sizeof(number_of_change_records); 212448761c62SAndrew Jeffery 212548761c62SAndrew Jeffery expected_size += 212648761c62SAndrew Jeffery sizeof(*event_data_operations) * number_of_change_records; 212748761c62SAndrew Jeffery expected_size += 212848761c62SAndrew Jeffery sizeof(*numbers_of_change_entries) * number_of_change_records; 212948761c62SAndrew Jeffery 213048761c62SAndrew Jeffery for (uint8_t i = 0; i < number_of_change_records; ++i) { 213148761c62SAndrew Jeffery expected_size += sizeof(*change_entries[0]) * 213248761c62SAndrew Jeffery numbers_of_change_entries[i]; 213348761c62SAndrew Jeffery } 213448761c62SAndrew Jeffery 213548761c62SAndrew Jeffery *actual_change_records_size = expected_size; 213648761c62SAndrew Jeffery 213748761c62SAndrew Jeffery if (event_data == NULL) { 213848761c62SAndrew Jeffery return PLDM_SUCCESS; 213948761c62SAndrew Jeffery } 214048761c62SAndrew Jeffery 214148761c62SAndrew Jeffery if (max_change_records_size < expected_size) { 214248761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 214348761c62SAndrew Jeffery } 214448761c62SAndrew Jeffery 214548761c62SAndrew Jeffery event_data->event_data_format = event_data_format; 214648761c62SAndrew Jeffery event_data->number_of_change_records = number_of_change_records; 214748761c62SAndrew Jeffery 214848761c62SAndrew Jeffery struct pldm_pdr_repository_change_record_data *record_data = 214948761c62SAndrew Jeffery (struct pldm_pdr_repository_change_record_data *) 215048761c62SAndrew Jeffery event_data->change_records; 215148761c62SAndrew Jeffery 215248761c62SAndrew Jeffery for (uint8_t i = 0; i < number_of_change_records; ++i) { 215348761c62SAndrew Jeffery record_data->event_data_operation = event_data_operations[i]; 215448761c62SAndrew Jeffery record_data->number_of_change_entries = 215548761c62SAndrew Jeffery numbers_of_change_entries[i]; 215648761c62SAndrew Jeffery 215748761c62SAndrew Jeffery for (uint8_t j = 0; j < record_data->number_of_change_entries; 215848761c62SAndrew Jeffery ++j) { 215948761c62SAndrew Jeffery record_data->change_entry[j] = 216048761c62SAndrew Jeffery htole32(change_entries[i][j]); 216148761c62SAndrew Jeffery } 216248761c62SAndrew Jeffery 216348761c62SAndrew Jeffery record_data = 216448761c62SAndrew Jeffery (struct pldm_pdr_repository_change_record_data 216548761c62SAndrew Jeffery *)(record_data->change_entry + 216648761c62SAndrew Jeffery record_data->number_of_change_entries); 216748761c62SAndrew Jeffery } 216848761c62SAndrew Jeffery 216948761c62SAndrew Jeffery return PLDM_SUCCESS; 217048761c62SAndrew Jeffery } 217148761c62SAndrew Jeffery 217248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 217348761c62SAndrew Jeffery int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data, 217448761c62SAndrew Jeffery size_t event_data_size, 217548761c62SAndrew Jeffery uint8_t *event_data_format, 217648761c62SAndrew Jeffery uint8_t *number_of_change_records, 217748761c62SAndrew Jeffery size_t *change_record_data_offset) 217848761c62SAndrew Jeffery { 217948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 218048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 218148761c62SAndrew Jeffery int rc; 218248761c62SAndrew Jeffery 218390bbe6c0SAndrew Jeffery if (event_data == NULL || event_data_format == NULL || 218490bbe6c0SAndrew Jeffery number_of_change_records == NULL || 218548761c62SAndrew Jeffery change_record_data_offset == NULL) { 218648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 218748761c62SAndrew Jeffery } 218848761c62SAndrew Jeffery 2189830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 2190830c1eb4SAndrew Jeffery PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH, 219148761c62SAndrew Jeffery event_data, event_data_size); 219248761c62SAndrew Jeffery if (rc) { 2193830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 219448761c62SAndrew Jeffery } 219548761c62SAndrew Jeffery 219648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_format); 219748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, number_of_change_records); 219848761c62SAndrew Jeffery 219948761c62SAndrew Jeffery *change_record_data_offset = 220048761c62SAndrew Jeffery sizeof(*event_data_format) + sizeof(*number_of_change_records); 220148761c62SAndrew Jeffery 2202830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2203830c1eb4SAndrew Jeffery if (rc) { 2204830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2205830c1eb4SAndrew Jeffery } 2206830c1eb4SAndrew Jeffery 2207830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 220848761c62SAndrew Jeffery } 220948761c62SAndrew Jeffery 2210f874b383SThu Nguyen LIBPLDM_ABI_STABLE 22117739d123SThu Nguyen int decode_pldm_message_poll_event_data( 22127739d123SThu Nguyen const void *event_data, size_t event_data_length, 22137739d123SThu Nguyen struct pldm_message_poll_event *poll_event) 221448761c62SAndrew Jeffery { 221548761c62SAndrew Jeffery struct pldm_msgbuf _buf; 221648761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 221748761c62SAndrew Jeffery int rc; 221848761c62SAndrew Jeffery 221990bbe6c0SAndrew Jeffery if (!event_data || !poll_event) { 22207739d123SThu Nguyen return -EINVAL; 222148761c62SAndrew Jeffery } 222248761c62SAndrew Jeffery 22237739d123SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 222448761c62SAndrew Jeffery event_data_length); 222548761c62SAndrew Jeffery if (rc) { 222648761c62SAndrew Jeffery return rc; 222748761c62SAndrew Jeffery } 222848761c62SAndrew Jeffery 22297739d123SThu Nguyen pldm_msgbuf_extract(buf, poll_event->format_version); 22307739d123SThu Nguyen rc = pldm_msgbuf_extract(buf, poll_event->event_id); 223148761c62SAndrew Jeffery if (rc) { 223248761c62SAndrew Jeffery return rc; 223348761c62SAndrew Jeffery } 223448761c62SAndrew Jeffery 22357739d123SThu Nguyen if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 22367739d123SThu Nguyen return -EPROTO; 223748761c62SAndrew Jeffery } 223848761c62SAndrew Jeffery 22397739d123SThu Nguyen pldm_msgbuf_extract(buf, poll_event->data_transfer_handle); 224048761c62SAndrew Jeffery 224148761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 224248761c62SAndrew Jeffery } 224348761c62SAndrew Jeffery 224448761c62SAndrew Jeffery LIBPLDM_ABI_TESTING 22457739d123SThu Nguyen int encode_pldm_message_poll_event_data( 22467739d123SThu Nguyen const struct pldm_message_poll_event *poll_event, void *event_data, 224748761c62SAndrew Jeffery size_t event_data_length) 224848761c62SAndrew Jeffery { 224948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 225048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 225148761c62SAndrew Jeffery int rc; 225248761c62SAndrew Jeffery 225390bbe6c0SAndrew Jeffery if (poll_event == NULL || event_data == NULL) { 225490bbe6c0SAndrew Jeffery return -EINVAL; 225590bbe6c0SAndrew Jeffery } 225690bbe6c0SAndrew Jeffery 22577739d123SThu Nguyen if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) { 22587739d123SThu Nguyen return -EPROTO; 225948761c62SAndrew Jeffery } 226048761c62SAndrew Jeffery 22617739d123SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data, 226248761c62SAndrew Jeffery event_data_length); 226348761c62SAndrew Jeffery if (rc) { 226448761c62SAndrew Jeffery return rc; 226548761c62SAndrew Jeffery } 22667739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->format_version); 22677739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->event_id); 22687739d123SThu Nguyen pldm_msgbuf_insert(buf, poll_event->data_transfer_handle); 226948761c62SAndrew Jeffery 22707739d123SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 227148761c62SAndrew Jeffery } 227248761c62SAndrew Jeffery 227348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 227448761c62SAndrew Jeffery int decode_pldm_pdr_repository_change_record_data( 227548761c62SAndrew Jeffery const uint8_t *change_record_data, size_t change_record_data_size, 227648761c62SAndrew Jeffery uint8_t *event_data_operation, uint8_t *number_of_change_entries, 227748761c62SAndrew Jeffery size_t *change_entry_data_offset) 227848761c62SAndrew Jeffery { 227948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 228048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 228148761c62SAndrew Jeffery int rc; 228248761c62SAndrew Jeffery 228390bbe6c0SAndrew Jeffery if (change_record_data == NULL || event_data_operation == NULL || 228490bbe6c0SAndrew Jeffery number_of_change_entries == NULL || 228548761c62SAndrew Jeffery change_entry_data_offset == NULL) { 228648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 228748761c62SAndrew Jeffery } 228848761c62SAndrew Jeffery 2289830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 2290830c1eb4SAndrew Jeffery buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH, 229148761c62SAndrew Jeffery change_record_data, change_record_data_size); 229248761c62SAndrew Jeffery if (rc) { 2293830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 229448761c62SAndrew Jeffery } 229548761c62SAndrew Jeffery 229648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_operation); 229748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, number_of_change_entries); 229848761c62SAndrew Jeffery 229948761c62SAndrew Jeffery *change_entry_data_offset = sizeof(*event_data_operation) + 230048761c62SAndrew Jeffery sizeof(*number_of_change_entries); 230148761c62SAndrew Jeffery 2302830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2303830c1eb4SAndrew Jeffery if (rc) { 2304830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2305830c1eb4SAndrew Jeffery } 2306830c1eb4SAndrew Jeffery 2307830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 230848761c62SAndrew Jeffery } 230948761c62SAndrew Jeffery 231048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 231148761c62SAndrew Jeffery int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id, 231248761c62SAndrew Jeffery uint8_t rearm_event_state, 231348761c62SAndrew Jeffery struct pldm_msg *msg) 231448761c62SAndrew Jeffery { 231548761c62SAndrew Jeffery if (msg == NULL) { 231648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 231748761c62SAndrew Jeffery } 231848761c62SAndrew Jeffery 231948761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 232048761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 232148761c62SAndrew Jeffery header.instance = instance_id; 232248761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 232348761c62SAndrew Jeffery header.command = PLDM_GET_SENSOR_READING; 232448761c62SAndrew Jeffery 232548761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 232648761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 232748761c62SAndrew Jeffery return rc; 232848761c62SAndrew Jeffery } 232948761c62SAndrew Jeffery 233048761c62SAndrew Jeffery struct pldm_get_sensor_reading_req *request = 233148761c62SAndrew Jeffery (struct pldm_get_sensor_reading_req *)msg->payload; 233248761c62SAndrew Jeffery 233348761c62SAndrew Jeffery request->sensor_id = htole16(sensor_id); 233448761c62SAndrew Jeffery request->rearm_event_state = rearm_event_state; 233548761c62SAndrew Jeffery 233648761c62SAndrew Jeffery return PLDM_SUCCESS; 233748761c62SAndrew Jeffery } 233848761c62SAndrew Jeffery 233948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 234048761c62SAndrew Jeffery int decode_get_sensor_reading_resp( 234148761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 234248761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *sensor_data_size, 234348761c62SAndrew Jeffery uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable, 234448761c62SAndrew Jeffery uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state, 234548761c62SAndrew Jeffery uint8_t *present_reading) 234648761c62SAndrew Jeffery { 234748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 234848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 234948761c62SAndrew Jeffery int rc; 235048761c62SAndrew Jeffery 235148761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || 235248761c62SAndrew Jeffery sensor_data_size == NULL || sensor_operational_state == NULL || 235348761c62SAndrew Jeffery sensor_event_message_enable == NULL || present_state == NULL || 235448761c62SAndrew Jeffery previous_state == NULL || event_state == NULL || 235548761c62SAndrew Jeffery present_reading == NULL) { 235648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 235748761c62SAndrew Jeffery } 235848761c62SAndrew Jeffery 2359830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES, 236048761c62SAndrew Jeffery msg->payload, payload_length); 236148761c62SAndrew Jeffery if (rc) { 2362830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 236348761c62SAndrew Jeffery } 236448761c62SAndrew Jeffery 236548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 236648761c62SAndrew Jeffery if (rc) { 2367830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 236848761c62SAndrew Jeffery } 236948761c62SAndrew Jeffery 237048761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 237148761c62SAndrew Jeffery return PLDM_SUCCESS; 237248761c62SAndrew Jeffery } 237348761c62SAndrew Jeffery 237448761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, sensor_data_size); 237548761c62SAndrew Jeffery if (rc) { 2376830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 237748761c62SAndrew Jeffery } 237848761c62SAndrew Jeffery 237948761c62SAndrew Jeffery if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) { 238048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 238148761c62SAndrew Jeffery } 238248761c62SAndrew Jeffery 238348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_operational_state); 238448761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_event_message_enable); 238548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, present_state); 238648761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, previous_state); 238748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_state); 238848761c62SAndrew Jeffery 238948761c62SAndrew Jeffery pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size, 239048761c62SAndrew Jeffery present_reading); 239148761c62SAndrew Jeffery 2392830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2393830c1eb4SAndrew Jeffery if (rc) { 2394830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2395830c1eb4SAndrew Jeffery } 2396830c1eb4SAndrew Jeffery 2397830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 239848761c62SAndrew Jeffery } 239948761c62SAndrew Jeffery 240048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 240148761c62SAndrew Jeffery int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code, 240248761c62SAndrew Jeffery uint8_t sensor_data_size, 240348761c62SAndrew Jeffery uint8_t sensor_operational_state, 240448761c62SAndrew Jeffery uint8_t sensor_event_message_enable, 240548761c62SAndrew Jeffery uint8_t present_state, 240648761c62SAndrew Jeffery uint8_t previous_state, uint8_t event_state, 240748761c62SAndrew Jeffery const uint8_t *present_reading, 240848761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 240948761c62SAndrew Jeffery { 241048761c62SAndrew Jeffery if (msg == NULL || present_reading == NULL) { 241148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 241248761c62SAndrew Jeffery } 241348761c62SAndrew Jeffery 241448761c62SAndrew Jeffery if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) { 241548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 241648761c62SAndrew Jeffery } 241748761c62SAndrew Jeffery 241848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 241948761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 242048761c62SAndrew Jeffery header.instance = instance_id; 242148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 242248761c62SAndrew Jeffery header.command = PLDM_GET_SENSOR_READING; 242348761c62SAndrew Jeffery 242448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 242548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 242648761c62SAndrew Jeffery return rc; 242748761c62SAndrew Jeffery } 242848761c62SAndrew Jeffery 242948761c62SAndrew Jeffery struct pldm_get_sensor_reading_resp *response = 243048761c62SAndrew Jeffery (struct pldm_get_sensor_reading_resp *)msg->payload; 243148761c62SAndrew Jeffery 243248761c62SAndrew Jeffery response->completion_code = completion_code; 243348761c62SAndrew Jeffery response->sensor_data_size = sensor_data_size; 243448761c62SAndrew Jeffery response->sensor_operational_state = sensor_operational_state; 243548761c62SAndrew Jeffery response->sensor_event_message_enable = sensor_event_message_enable; 243648761c62SAndrew Jeffery response->present_state = present_state; 243748761c62SAndrew Jeffery response->previous_state = previous_state; 243848761c62SAndrew Jeffery response->event_state = event_state; 243948761c62SAndrew Jeffery 244048761c62SAndrew Jeffery if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 || 244148761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) { 244248761c62SAndrew Jeffery if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) { 244348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 244448761c62SAndrew Jeffery } 244548761c62SAndrew Jeffery response->present_reading[0] = *present_reading; 244648761c62SAndrew Jeffery 244748761c62SAndrew Jeffery } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 || 244848761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) { 244948761c62SAndrew Jeffery if (payload_length != 245048761c62SAndrew Jeffery PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) { 245148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 245248761c62SAndrew Jeffery } 245348761c62SAndrew Jeffery uint16_t val = *(uint16_t *)present_reading; 245448761c62SAndrew Jeffery val = htole16(val); 245548761c62SAndrew Jeffery memcpy(response->present_reading, &val, 2); 245648761c62SAndrew Jeffery 245748761c62SAndrew Jeffery } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 || 245848761c62SAndrew Jeffery sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) { 245948761c62SAndrew Jeffery if (payload_length != 246048761c62SAndrew Jeffery PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) { 246148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_LENGTH; 246248761c62SAndrew Jeffery } 246348761c62SAndrew Jeffery uint32_t val = *(uint32_t *)present_reading; 246448761c62SAndrew Jeffery val = htole32(val); 246548761c62SAndrew Jeffery memcpy(response->present_reading, &val, 4); 246648761c62SAndrew Jeffery } 246748761c62SAndrew Jeffery 246848761c62SAndrew Jeffery return PLDM_SUCCESS; 246948761c62SAndrew Jeffery } 247048761c62SAndrew Jeffery 247148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 247248761c62SAndrew Jeffery int decode_get_sensor_reading_req(const struct pldm_msg *msg, 247348761c62SAndrew Jeffery size_t payload_length, uint16_t *sensor_id, 247448761c62SAndrew Jeffery uint8_t *rearm_event_state) 247548761c62SAndrew Jeffery { 247648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 247748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 247848761c62SAndrew Jeffery int rc; 247948761c62SAndrew Jeffery 248048761c62SAndrew Jeffery if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) { 248148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 248248761c62SAndrew Jeffery } 248348761c62SAndrew Jeffery 2484830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES, 248548761c62SAndrew Jeffery msg->payload, payload_length); 248648761c62SAndrew Jeffery if (rc) { 2487830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 248848761c62SAndrew Jeffery } 248948761c62SAndrew Jeffery 249048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, sensor_id); 249148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, rearm_event_state); 249248761c62SAndrew Jeffery 2493830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2494830c1eb4SAndrew Jeffery if (rc) { 2495830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2496830c1eb4SAndrew Jeffery } 2497830c1eb4SAndrew Jeffery 2498830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 249948761c62SAndrew Jeffery } 250048761c62SAndrew Jeffery 250148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 250248761c62SAndrew Jeffery int encode_set_event_receiver_req(uint8_t instance_id, 250348761c62SAndrew Jeffery uint8_t event_message_global_enable, 250448761c62SAndrew Jeffery uint8_t transport_protocol_type, 250548761c62SAndrew Jeffery uint8_t event_receiver_address_info, 250648761c62SAndrew Jeffery uint16_t heartbeat_timer, 250748761c62SAndrew Jeffery struct pldm_msg *msg) 250848761c62SAndrew Jeffery { 250948761c62SAndrew Jeffery if (msg == NULL) { 251048761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 251148761c62SAndrew Jeffery } 251248761c62SAndrew Jeffery 251348761c62SAndrew Jeffery if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) { 251448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 251548761c62SAndrew Jeffery } 251648761c62SAndrew Jeffery 251748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 251848761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 251948761c62SAndrew Jeffery header.instance = instance_id; 252048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 252148761c62SAndrew Jeffery header.command = PLDM_SET_EVENT_RECEIVER; 252248761c62SAndrew Jeffery 252348761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 252448761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 252548761c62SAndrew Jeffery return rc; 252648761c62SAndrew Jeffery } 252748761c62SAndrew Jeffery 252848761c62SAndrew Jeffery struct pldm_set_event_receiver_req *request = 252948761c62SAndrew Jeffery (struct pldm_set_event_receiver_req *)msg->payload; 253048761c62SAndrew Jeffery request->event_message_global_enable = event_message_global_enable; 253148761c62SAndrew Jeffery 253248761c62SAndrew Jeffery request->transport_protocol_type = transport_protocol_type; 253348761c62SAndrew Jeffery request->event_receiver_address_info = event_receiver_address_info; 253448761c62SAndrew Jeffery 253548761c62SAndrew Jeffery if (event_message_global_enable == 253648761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) { 253748761c62SAndrew Jeffery if (heartbeat_timer == 0) { 253848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 253948761c62SAndrew Jeffery } 254048761c62SAndrew Jeffery request->heartbeat_timer = htole16(heartbeat_timer); 254148761c62SAndrew Jeffery } 254248761c62SAndrew Jeffery 254348761c62SAndrew Jeffery return PLDM_SUCCESS; 254448761c62SAndrew Jeffery } 254548761c62SAndrew Jeffery 254648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 254748761c62SAndrew Jeffery int decode_set_event_receiver_resp(const struct pldm_msg *msg, 254848761c62SAndrew Jeffery size_t payload_length, 254948761c62SAndrew Jeffery uint8_t *completion_code) 255048761c62SAndrew Jeffery { 255148761c62SAndrew Jeffery struct pldm_msgbuf _buf; 255248761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 255348761c62SAndrew Jeffery int rc; 255448761c62SAndrew Jeffery 255548761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL) { 255648761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 255748761c62SAndrew Jeffery } 255848761c62SAndrew Jeffery 2559830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES, 256048761c62SAndrew Jeffery msg->payload, payload_length); 256148761c62SAndrew Jeffery if (rc) { 2562830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 256348761c62SAndrew Jeffery } 256448761c62SAndrew Jeffery 256548761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, completion_code); 256648761c62SAndrew Jeffery 2567830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2568830c1eb4SAndrew Jeffery if (rc) { 2569830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2570830c1eb4SAndrew Jeffery } 2571830c1eb4SAndrew Jeffery 2572830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 257348761c62SAndrew Jeffery } 257448761c62SAndrew Jeffery 257548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 257648761c62SAndrew Jeffery int decode_set_event_receiver_req(const struct pldm_msg *msg, 257748761c62SAndrew Jeffery size_t payload_length, 257848761c62SAndrew Jeffery uint8_t *event_message_global_enable, 257948761c62SAndrew Jeffery uint8_t *transport_protocol_type, 258048761c62SAndrew Jeffery uint8_t *event_receiver_address_info, 258148761c62SAndrew Jeffery uint16_t *heartbeat_timer) 258248761c62SAndrew Jeffery 258348761c62SAndrew Jeffery { 258448761c62SAndrew Jeffery struct pldm_msgbuf _buf; 258548761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 258648761c62SAndrew Jeffery int rc; 258748761c62SAndrew Jeffery 258848761c62SAndrew Jeffery if (msg == NULL || event_message_global_enable == NULL || 258948761c62SAndrew Jeffery transport_protocol_type == NULL || 259048761c62SAndrew Jeffery event_receiver_address_info == NULL || heartbeat_timer == NULL) { 259148761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 259248761c62SAndrew Jeffery } 259348761c62SAndrew Jeffery 2594830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES, 259548761c62SAndrew Jeffery msg->payload, payload_length); 259648761c62SAndrew Jeffery if (rc) { 2597830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 259848761c62SAndrew Jeffery } 259948761c62SAndrew Jeffery 260048761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_message_global_enable); 260148761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, transport_protocol_type); 260248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_receiver_address_info); 260348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, heartbeat_timer); 260448761c62SAndrew Jeffery 260548761c62SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 260648761c62SAndrew Jeffery if (rc) { 2607830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 260848761c62SAndrew Jeffery } 260948761c62SAndrew Jeffery 261048761c62SAndrew Jeffery if ((*event_message_global_enable == 261148761c62SAndrew Jeffery PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) && 261248761c62SAndrew Jeffery (*heartbeat_timer == 0)) { 261348761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 261448761c62SAndrew Jeffery } 261548761c62SAndrew Jeffery 261648761c62SAndrew Jeffery return PLDM_SUCCESS; 261748761c62SAndrew Jeffery } 261848761c62SAndrew Jeffery 261948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 262048761c62SAndrew Jeffery int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code, 262148761c62SAndrew Jeffery struct pldm_msg *msg) 262248761c62SAndrew Jeffery 262348761c62SAndrew Jeffery { 262448761c62SAndrew Jeffery if (msg == NULL) { 262548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 262648761c62SAndrew Jeffery } 262748761c62SAndrew Jeffery 262848761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 262948761c62SAndrew Jeffery header.instance = instance_id; 263048761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 263148761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 263248761c62SAndrew Jeffery header.command = PLDM_SET_EVENT_RECEIVER; 263348761c62SAndrew Jeffery 263448761c62SAndrew Jeffery uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); 263548761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 263648761c62SAndrew Jeffery return rc; 263748761c62SAndrew Jeffery } 263848761c62SAndrew Jeffery 263948761c62SAndrew Jeffery msg->payload[0] = completion_code; 264048761c62SAndrew Jeffery 264148761c62SAndrew Jeffery return PLDM_SUCCESS; 264248761c62SAndrew Jeffery } 264348761c62SAndrew Jeffery 264448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 264548761c62SAndrew Jeffery int encode_poll_for_platform_event_message_req(uint8_t instance_id, 264648761c62SAndrew Jeffery uint8_t format_version, 264748761c62SAndrew Jeffery uint8_t transfer_operation_flag, 264848761c62SAndrew Jeffery uint32_t data_transfer_handle, 264948761c62SAndrew Jeffery uint16_t event_id_to_acknowledge, 265048761c62SAndrew Jeffery struct pldm_msg *msg, 265148761c62SAndrew Jeffery size_t payload_length) 265248761c62SAndrew Jeffery { 265348761c62SAndrew Jeffery struct pldm_msgbuf _buf; 265448761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 265548761c62SAndrew Jeffery int rc; 265648761c62SAndrew Jeffery 265748761c62SAndrew Jeffery if (msg == NULL) { 265848761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 265948761c62SAndrew Jeffery } 266048761c62SAndrew Jeffery 2661387b10f6SThu Nguyen rc = pldm_platform_poll_for_platform_event_message_validate( 2662387b10f6SThu Nguyen transfer_operation_flag, event_id_to_acknowledge); 2663387b10f6SThu Nguyen if (rc < 0) { 2664387b10f6SThu Nguyen return PLDM_ERROR_INVALID_DATA; 2665387b10f6SThu Nguyen } 2666387b10f6SThu Nguyen 266748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 266848761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 266948761c62SAndrew Jeffery header.instance = instance_id; 267048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 267148761c62SAndrew Jeffery header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE; 267248761c62SAndrew Jeffery 267348761c62SAndrew Jeffery rc = pack_pldm_header(&header, &(msg->hdr)); 267448761c62SAndrew Jeffery if (rc != PLDM_SUCCESS) { 267548761c62SAndrew Jeffery return rc; 267648761c62SAndrew Jeffery } 267748761c62SAndrew Jeffery 2678830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 267948761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 268048761c62SAndrew Jeffery msg->payload, payload_length); 268148761c62SAndrew Jeffery if (rc) { 2682830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 268348761c62SAndrew Jeffery } 268448761c62SAndrew Jeffery 268548761c62SAndrew Jeffery pldm_msgbuf_insert(buf, format_version); 268648761c62SAndrew Jeffery pldm_msgbuf_insert(buf, transfer_operation_flag); 268748761c62SAndrew Jeffery pldm_msgbuf_insert(buf, data_transfer_handle); 268848761c62SAndrew Jeffery pldm_msgbuf_insert(buf, event_id_to_acknowledge); 268948761c62SAndrew Jeffery 2690830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy(buf); 2691830c1eb4SAndrew Jeffery if (rc) { 2692830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2693830c1eb4SAndrew Jeffery } 2694830c1eb4SAndrew Jeffery 2695830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 269648761c62SAndrew Jeffery } 269748761c62SAndrew Jeffery 269848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE 269948761c62SAndrew Jeffery int decode_poll_for_platform_event_message_resp( 270048761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 270148761c62SAndrew Jeffery uint8_t *completion_code, uint8_t *tid, uint16_t *event_id, 270248761c62SAndrew Jeffery uint32_t *next_data_transfer_handle, uint8_t *transfer_flag, 270348761c62SAndrew Jeffery uint8_t *event_class, uint32_t *event_data_size, void **event_data, 270448761c62SAndrew Jeffery uint32_t *event_data_integrity_checksum) 270548761c62SAndrew Jeffery { 270648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 270748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 270848761c62SAndrew Jeffery int rc; 270948761c62SAndrew Jeffery 271048761c62SAndrew Jeffery if (msg == NULL || completion_code == NULL || tid == NULL || 271148761c62SAndrew Jeffery event_id == NULL || next_data_transfer_handle == NULL || 271248761c62SAndrew Jeffery transfer_flag == NULL || event_class == NULL || 271348761c62SAndrew Jeffery event_data_size == NULL || event_data == NULL || 271448761c62SAndrew Jeffery event_data_integrity_checksum == NULL) { 271548761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 271648761c62SAndrew Jeffery } 271748761c62SAndrew Jeffery 2718830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno( 271948761c62SAndrew Jeffery buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES, 272048761c62SAndrew Jeffery msg->payload, payload_length); 272148761c62SAndrew Jeffery if (rc) { 2722830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 272348761c62SAndrew Jeffery } 272448761c62SAndrew Jeffery 272548761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, completion_code); 272648761c62SAndrew Jeffery if (rc) { 2727830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 272848761c62SAndrew Jeffery } 272948761c62SAndrew Jeffery if (PLDM_SUCCESS != *completion_code) { 273048761c62SAndrew Jeffery return *completion_code; 273148761c62SAndrew Jeffery } 273248761c62SAndrew Jeffery 273348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, tid); 273448761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_id); 273548761c62SAndrew Jeffery if (rc) { 2736830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 273748761c62SAndrew Jeffery } 273848761c62SAndrew Jeffery if ((*event_id == 0) || (*event_id == 0xffff)) { 273948761c62SAndrew Jeffery return PLDM_SUCCESS; 274048761c62SAndrew Jeffery } 274148761c62SAndrew Jeffery 274248761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, next_data_transfer_handle); 274348761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, transfer_flag); 274448761c62SAndrew Jeffery if (rc) { 2745830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 274648761c62SAndrew Jeffery } 274748761c62SAndrew Jeffery 274848761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_class); 274948761c62SAndrew Jeffery rc = pldm_msgbuf_extract_p(buf, event_data_size); 275048761c62SAndrew Jeffery if (rc) { 2751830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 275248761c62SAndrew Jeffery } 275348761c62SAndrew Jeffery if (*event_data_size > payload_length) { 275448761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 275548761c62SAndrew Jeffery } 275648761c62SAndrew Jeffery 275748761c62SAndrew Jeffery if (*event_data_size > 0) { 275848761c62SAndrew Jeffery pldm_msgbuf_span_required(buf, *event_data_size, event_data); 275948761c62SAndrew Jeffery } 276048761c62SAndrew Jeffery 276148761c62SAndrew Jeffery if (*transfer_flag == PLDM_END || 276248761c62SAndrew Jeffery *transfer_flag == PLDM_START_AND_END) { 276348761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, event_data_integrity_checksum); 276448761c62SAndrew Jeffery } 276548761c62SAndrew Jeffery 2766830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2767830c1eb4SAndrew Jeffery if (rc) { 2768830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2769830c1eb4SAndrew Jeffery } 2770830c1eb4SAndrew Jeffery 2771830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 277248761c62SAndrew Jeffery } 277348761c62SAndrew Jeffery 277448761c62SAndrew Jeffery LIBPLDM_ABI_TESTING 277548761c62SAndrew Jeffery int decode_numeric_effecter_pdr_data( 277648761c62SAndrew Jeffery const void *pdr_data, size_t pdr_data_length, 277748761c62SAndrew Jeffery struct pldm_numeric_effecter_value_pdr *pdr_value) 277848761c62SAndrew Jeffery { 277948761c62SAndrew Jeffery struct pldm_msgbuf _buf; 278048761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 278148761c62SAndrew Jeffery struct pldm_value_pdr_hdr hdr; 278248761c62SAndrew Jeffery int rc; 278348761c62SAndrew Jeffery 278490bbe6c0SAndrew Jeffery if (!pdr_data || !pdr_value) { 278590bbe6c0SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 278690bbe6c0SAndrew Jeffery } 278790bbe6c0SAndrew Jeffery 2788830c1eb4SAndrew Jeffery rc = pldm_msgbuf_init_errno(buf, 2789830c1eb4SAndrew Jeffery PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 279048761c62SAndrew Jeffery pdr_data, pdr_data_length); 279148761c62SAndrew Jeffery if (rc) { 2792830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 279348761c62SAndrew Jeffery } 279448761c62SAndrew Jeffery 2795329176a8SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr( 2796329176a8SAndrew Jeffery buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH, 279748761c62SAndrew Jeffery pdr_data_length); 279848761c62SAndrew Jeffery if (rc) { 2799329176a8SAndrew Jeffery return pldm_xlate_errno(rc); 280048761c62SAndrew Jeffery } 280148761c62SAndrew Jeffery 280248761c62SAndrew Jeffery memcpy(&pdr_value->hdr, &hdr, sizeof(hdr)); 280348761c62SAndrew Jeffery 280448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->terminus_handle); 280548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_id); 280648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_type); 280748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->entity_instance); 280848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->container_id); 280948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id); 281048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_init); 281148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names); 281248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_unit); 281348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->unit_modifier); 281448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->rate_unit); 281548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle); 281648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit); 281748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier); 281848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit); 281948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle); 282048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->is_linear); 282148761c62SAndrew Jeffery 282248761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size); 282348761c62SAndrew Jeffery if (rc) { 2824830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 282548761c62SAndrew Jeffery } 282648761c62SAndrew Jeffery if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) { 282748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 282848761c62SAndrew Jeffery } 282948761c62SAndrew Jeffery 283048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->resolution); 283148761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->offset); 283248761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->accuracy); 283348761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->plus_tolerance); 283448761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->minus_tolerance); 283548761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->state_transition_interval); 283648761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->transition_interval); 283748761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 283848761c62SAndrew Jeffery pdr_value->max_settable); 283948761c62SAndrew Jeffery pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size, 284048761c62SAndrew Jeffery pdr_value->min_settable); 284148761c62SAndrew Jeffery 284248761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format); 284348761c62SAndrew Jeffery if (rc) { 2844830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 284548761c62SAndrew Jeffery } 284648761c62SAndrew Jeffery if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) { 284748761c62SAndrew Jeffery return PLDM_ERROR_INVALID_DATA; 284848761c62SAndrew Jeffery } 284948761c62SAndrew Jeffery 285048761c62SAndrew Jeffery pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte); 285148761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 285248761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->nominal_value); 285348761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 285448761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_max); 285548761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 285648761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->normal_min); 285748761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 285848761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->rated_max); 285948761c62SAndrew Jeffery pldm_msgbuf_extract_range_field_format( 286048761c62SAndrew Jeffery buf, pdr_value->range_field_format, pdr_value->rated_min); 286148761c62SAndrew Jeffery 2862830c1eb4SAndrew Jeffery rc = pldm_msgbuf_destroy_consumed(buf); 2863830c1eb4SAndrew Jeffery if (rc) { 2864830c1eb4SAndrew Jeffery return pldm_xlate_errno(rc); 2865830c1eb4SAndrew Jeffery } 2866830c1eb4SAndrew Jeffery 2867830c1eb4SAndrew Jeffery return PLDM_SUCCESS; 286848761c62SAndrew Jeffery } 286948761c62SAndrew Jeffery 2870de67ab62STal Yacobi LIBPLDM_ABI_STABLE 287148761c62SAndrew Jeffery int encode_get_state_effecter_states_req(uint8_t instance_id, 287248761c62SAndrew Jeffery uint16_t effecter_id, 287348761c62SAndrew Jeffery struct pldm_msg *msg, 287448761c62SAndrew Jeffery size_t payload_length) 287548761c62SAndrew Jeffery { 287648761c62SAndrew Jeffery struct pldm_msgbuf _buf; 287748761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 287848761c62SAndrew Jeffery int rc; 287948761c62SAndrew Jeffery 288048761c62SAndrew Jeffery if (msg == NULL) { 2881f490a38fSTal Yacobi return -EINVAL; 288248761c62SAndrew Jeffery } 288348761c62SAndrew Jeffery 288448761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 288548761c62SAndrew Jeffery header.msg_type = PLDM_REQUEST; 288648761c62SAndrew Jeffery header.instance = instance_id; 288748761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 288848761c62SAndrew Jeffery header.command = PLDM_GET_STATE_EFFECTER_STATES; 288948761c62SAndrew Jeffery 2890f490a38fSTal Yacobi rc = pack_pldm_header_errno(&header, &msg->hdr); 2891f490a38fSTal Yacobi if (rc < 0) { 289248761c62SAndrew Jeffery return rc; 289348761c62SAndrew Jeffery } 289448761c62SAndrew Jeffery 2895f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno(buf, 2896f490a38fSTal Yacobi PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES, 289748761c62SAndrew Jeffery msg->payload, payload_length); 289848761c62SAndrew Jeffery if (rc) { 289948761c62SAndrew Jeffery return rc; 290048761c62SAndrew Jeffery } 290148761c62SAndrew Jeffery 290248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, effecter_id); 290348761c62SAndrew Jeffery 290448761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 290548761c62SAndrew Jeffery } 290648761c62SAndrew Jeffery 2907de67ab62STal Yacobi LIBPLDM_ABI_STABLE 290848761c62SAndrew Jeffery int decode_get_state_effecter_states_req(const struct pldm_msg *msg, 290948761c62SAndrew Jeffery size_t payload_length, 291048761c62SAndrew Jeffery uint16_t *effecter_id) 291148761c62SAndrew Jeffery { 291248761c62SAndrew Jeffery struct pldm_msgbuf _buf; 291348761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 291448761c62SAndrew Jeffery int rc; 291548761c62SAndrew Jeffery 291648761c62SAndrew Jeffery if (msg == NULL || effecter_id == NULL) { 2917f490a38fSTal Yacobi return -EINVAL; 291848761c62SAndrew Jeffery } 291948761c62SAndrew Jeffery 2920f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 2921f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 292248761c62SAndrew Jeffery msg->payload, payload_length); 292348761c62SAndrew Jeffery if (rc) { 292448761c62SAndrew Jeffery return rc; 292548761c62SAndrew Jeffery } 292648761c62SAndrew Jeffery 292748761c62SAndrew Jeffery pldm_msgbuf_extract_p(buf, effecter_id); 292848761c62SAndrew Jeffery 292948761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 293048761c62SAndrew Jeffery } 293148761c62SAndrew Jeffery 2932de67ab62STal Yacobi LIBPLDM_ABI_STABLE 293348761c62SAndrew Jeffery int decode_get_state_effecter_states_resp( 293448761c62SAndrew Jeffery const struct pldm_msg *msg, size_t payload_length, 293548761c62SAndrew Jeffery struct pldm_get_state_effecter_states_resp *resp) 293648761c62SAndrew Jeffery { 293748761c62SAndrew Jeffery struct pldm_msgbuf _buf; 293848761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 293948761c62SAndrew Jeffery get_effecter_state_field *field; 294048761c62SAndrew Jeffery int rc; 294148761c62SAndrew Jeffery int i; 294248761c62SAndrew Jeffery 294348761c62SAndrew Jeffery if (msg == NULL || resp == NULL) { 2944f490a38fSTal Yacobi return -EINVAL; 294548761c62SAndrew Jeffery } 294648761c62SAndrew Jeffery 2947f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 2948f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 294948761c62SAndrew Jeffery msg->payload, payload_length); 295048761c62SAndrew Jeffery if (rc) { 295148761c62SAndrew Jeffery return rc; 295248761c62SAndrew Jeffery } 295348761c62SAndrew Jeffery 295448761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->completion_code); 295548761c62SAndrew Jeffery if (rc) { 295648761c62SAndrew Jeffery return rc; 295748761c62SAndrew Jeffery } 295848761c62SAndrew Jeffery 295948761c62SAndrew Jeffery if (PLDM_SUCCESS != resp->completion_code) { 2960f490a38fSTal Yacobi return 0; 296148761c62SAndrew Jeffery } 296248761c62SAndrew Jeffery 296348761c62SAndrew Jeffery rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count); 296448761c62SAndrew Jeffery if (rc) { 296548761c62SAndrew Jeffery return rc; 296648761c62SAndrew Jeffery } 296748761c62SAndrew Jeffery 296848761c62SAndrew Jeffery uint8_t comp_effecter_count = resp->comp_effecter_count; 296948761c62SAndrew Jeffery 297048761c62SAndrew Jeffery if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 297148761c62SAndrew Jeffery comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 2972f490a38fSTal Yacobi return -EBADMSG; 297348761c62SAndrew Jeffery } 297448761c62SAndrew Jeffery 297548761c62SAndrew Jeffery for (i = 0, field = resp->field; i < comp_effecter_count; 297648761c62SAndrew Jeffery i++, field++) { 297748761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->effecter_op_state); 297848761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->pending_state); 297948761c62SAndrew Jeffery pldm_msgbuf_extract(buf, field->present_state); 298048761c62SAndrew Jeffery } 298148761c62SAndrew Jeffery 298248761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 298348761c62SAndrew Jeffery } 298448761c62SAndrew Jeffery 2985de67ab62STal Yacobi LIBPLDM_ABI_STABLE 298648761c62SAndrew Jeffery int encode_get_state_effecter_states_resp( 298748761c62SAndrew Jeffery uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp, 298848761c62SAndrew Jeffery struct pldm_msg *msg, size_t payload_length) 298948761c62SAndrew Jeffery { 299048761c62SAndrew Jeffery struct pldm_msgbuf _buf; 299148761c62SAndrew Jeffery struct pldm_msgbuf *buf = &_buf; 299248761c62SAndrew Jeffery get_effecter_state_field *field; 299348761c62SAndrew Jeffery int rc; 299448761c62SAndrew Jeffery int i; 299548761c62SAndrew Jeffery 299648761c62SAndrew Jeffery if (msg == NULL || resp == NULL) { 2997f490a38fSTal Yacobi return -EINVAL; 299848761c62SAndrew Jeffery } 299948761c62SAndrew Jeffery 300048761c62SAndrew Jeffery uint8_t comp_effecter_count = resp->comp_effecter_count; 300148761c62SAndrew Jeffery 300248761c62SAndrew Jeffery if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN || 300348761c62SAndrew Jeffery comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) { 3004f490a38fSTal Yacobi return -EBADMSG; 300548761c62SAndrew Jeffery } 300648761c62SAndrew Jeffery 300748761c62SAndrew Jeffery struct pldm_header_info header = { 0 }; 300848761c62SAndrew Jeffery header.msg_type = PLDM_RESPONSE; 300948761c62SAndrew Jeffery header.instance = instance_id; 301048761c62SAndrew Jeffery header.pldm_type = PLDM_PLATFORM; 301148761c62SAndrew Jeffery header.command = PLDM_GET_STATE_EFFECTER_STATES; 301248761c62SAndrew Jeffery 3013f490a38fSTal Yacobi rc = pack_pldm_header_errno(&header, &msg->hdr); 3014f490a38fSTal Yacobi if (rc < 0) { 301548761c62SAndrew Jeffery return rc; 301648761c62SAndrew Jeffery } 301748761c62SAndrew Jeffery 3018f490a38fSTal Yacobi rc = pldm_msgbuf_init_errno( 3019f490a38fSTal Yacobi buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES, 302048761c62SAndrew Jeffery msg->payload, payload_length); 302148761c62SAndrew Jeffery if (rc) { 302248761c62SAndrew Jeffery return rc; 302348761c62SAndrew Jeffery } 302448761c62SAndrew Jeffery 302548761c62SAndrew Jeffery pldm_msgbuf_insert(buf, resp->completion_code); 302648761c62SAndrew Jeffery pldm_msgbuf_insert(buf, comp_effecter_count); 302748761c62SAndrew Jeffery 302848761c62SAndrew Jeffery for (i = 0, field = resp->field; i < comp_effecter_count; 302948761c62SAndrew Jeffery i++, field++) { 303048761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->effecter_op_state); 303148761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->pending_state); 303248761c62SAndrew Jeffery pldm_msgbuf_insert(buf, field->present_state); 303348761c62SAndrew Jeffery } 303448761c62SAndrew Jeffery 303548761c62SAndrew Jeffery return pldm_msgbuf_destroy_consumed(buf); 303648761c62SAndrew Jeffery } 3037dacfa354SThu Nguyen 303843cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE 3039dacfa354SThu Nguyen int decode_entity_auxiliary_names_pdr( 3040dacfa354SThu Nguyen const void *data, size_t data_length, 3041dacfa354SThu Nguyen struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length) 3042dacfa354SThu Nguyen { 3043dacfa354SThu Nguyen struct pldm_msgbuf _buf; 3044dacfa354SThu Nguyen struct pldm_msgbuf *buf = &_buf; 3045dacfa354SThu Nguyen struct pldm_msgbuf _src; 3046dacfa354SThu Nguyen struct pldm_msgbuf *src = &_src; 3047dacfa354SThu Nguyen struct pldm_msgbuf _dst; 3048dacfa354SThu Nguyen struct pldm_msgbuf *dst = &_dst; 3049dacfa354SThu Nguyen size_t names_len = 0; 3050dacfa354SThu Nguyen void *names = NULL; 3051dacfa354SThu Nguyen int rc; 3052dacfa354SThu Nguyen int i; 3053dacfa354SThu Nguyen 305490bbe6c0SAndrew Jeffery if (!data || !pdr) { 305590bbe6c0SAndrew Jeffery return -EINVAL; 305690bbe6c0SAndrew Jeffery } 305790bbe6c0SAndrew Jeffery 3058dacfa354SThu Nguyen /* 3059dacfa354SThu Nguyen * Alignment of auxiliary_name_data is an invariant as we statically assert 3060dacfa354SThu Nguyen * its behaviour in the header. 3061dacfa354SThu Nguyen */ 3062dacfa354SThu Nguyen assert(!((uintptr_t)pdr->auxiliary_name_data & 3063dacfa354SThu Nguyen (alignof(pldm_utf16be) - 1))); 3064dacfa354SThu Nguyen 3065dacfa354SThu Nguyen /* Reject any lengths that are obviously invalid */ 3066dacfa354SThu Nguyen if (pdr_length < data_length || pdr_length < sizeof(*pdr)) { 3067dacfa354SThu Nguyen return -EINVAL; 3068dacfa354SThu Nguyen } 3069dacfa354SThu Nguyen 3070dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno( 3071dacfa354SThu Nguyen buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data, 3072dacfa354SThu Nguyen data_length); 3073dacfa354SThu Nguyen if (rc) { 3074dacfa354SThu Nguyen return rc; 3075dacfa354SThu Nguyen } 3076dacfa354SThu Nguyen 3077329176a8SAndrew Jeffery rc = pldm_msgbuf_extract_value_pdr_hdr( 3078329176a8SAndrew Jeffery buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, 3079dacfa354SThu Nguyen data_length); 3080dacfa354SThu Nguyen if (rc) { 3081dacfa354SThu Nguyen return rc; 3082dacfa354SThu Nguyen } 3083dacfa354SThu Nguyen 3084dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_type); 3085dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_instance_num); 3086dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->container.entity_container_id); 3087dacfa354SThu Nguyen pldm_msgbuf_extract(buf, pdr->shared_name_count); 3088dacfa354SThu Nguyen rc = pldm_msgbuf_extract(buf, pdr->name_string_count); 3089dacfa354SThu Nguyen if (rc < 0) { 3090dacfa354SThu Nguyen return rc; 3091dacfa354SThu Nguyen } 3092dacfa354SThu Nguyen 3093dacfa354SThu Nguyen rc = pldm_msgbuf_span_remaining(buf, &names, &names_len); 3094dacfa354SThu Nguyen if (rc < 0) { 3095dacfa354SThu Nguyen return rc; 3096dacfa354SThu Nguyen } 309790bbe6c0SAndrew Jeffery assert(names); 3098dacfa354SThu Nguyen 3099dacfa354SThu Nguyen pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr); 3100dacfa354SThu Nguyen 3101dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size, 3102dacfa354SThu Nguyen pdr->auxiliary_name_data, 3103dacfa354SThu Nguyen pdr->auxiliary_name_data_size); 3104dacfa354SThu Nguyen if (rc < 0) { 3105dacfa354SThu Nguyen return rc; 3106dacfa354SThu Nguyen } 3107dacfa354SThu Nguyen 3108dacfa354SThu Nguyen /* 3109dacfa354SThu Nguyen * Below we do two passes over the same region. This is to first pack the 3110dacfa354SThu Nguyen * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings, 3111dacfa354SThu Nguyen * to maintain appropriate alignment. 3112dacfa354SThu Nguyen */ 3113dacfa354SThu Nguyen 3114dacfa354SThu Nguyen /* Initialise for the first pass to extract the UTF16-BE name strings */ 3115dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 3116dacfa354SThu Nguyen if (rc < 0) { 3117dacfa354SThu Nguyen return rc; 3118dacfa354SThu Nguyen } 3119dacfa354SThu Nguyen 3120dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3121dacfa354SThu Nguyen pldm_msgbuf_span_string_ascii(src, NULL, NULL); 31220a1be3cbSAndrew Jeffery rc = pldm_msgbuf_copy_string_utf16(dst, src); 31230a1be3cbSAndrew Jeffery if (rc) { 31240a1be3cbSAndrew Jeffery return rc; 31250a1be3cbSAndrew Jeffery } 3126dacfa354SThu Nguyen } 3127dacfa354SThu Nguyen 3128dacfa354SThu Nguyen rc = pldm_msgbuf_destroy_consumed(src); 3129dacfa354SThu Nguyen if (rc < 0) { 3130dacfa354SThu Nguyen return rc; 3131dacfa354SThu Nguyen } 3132dacfa354SThu Nguyen 3133dacfa354SThu Nguyen /* Reinitialise for the second pass to extract the ASCII tag strings */ 3134dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno(src, names_len, names, names_len); 3135dacfa354SThu Nguyen if (rc < 0) { 3136dacfa354SThu Nguyen return rc; 3137dacfa354SThu Nguyen } 3138dacfa354SThu Nguyen 3139dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 31400a1be3cbSAndrew Jeffery rc = pldm_msgbuf_copy_string_ascii(dst, src); 31410a1be3cbSAndrew Jeffery if (rc) { 31420a1be3cbSAndrew Jeffery return rc; 31430a1be3cbSAndrew Jeffery } 3144dacfa354SThu Nguyen pldm_msgbuf_span_string_utf16(src, NULL, NULL); 3145dacfa354SThu Nguyen } 3146dacfa354SThu Nguyen 3147dacfa354SThu Nguyen if ((rc = pldm_msgbuf_destroy(dst)) || 3148dacfa354SThu Nguyen (rc = pldm_msgbuf_destroy(src)) || 3149dacfa354SThu Nguyen (rc = pldm_msgbuf_destroy(buf))) { 3150dacfa354SThu Nguyen return rc; 3151dacfa354SThu Nguyen } 3152dacfa354SThu Nguyen 3153dacfa354SThu Nguyen return 0; 3154dacfa354SThu Nguyen } 3155dacfa354SThu Nguyen 315643cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE 3157dacfa354SThu Nguyen int decode_pldm_entity_auxiliary_names_pdr_index( 3158dacfa354SThu Nguyen struct pldm_entity_auxiliary_names_pdr *pdr) 3159dacfa354SThu Nguyen { 3160dacfa354SThu Nguyen struct pldm_msgbuf _buf; 3161dacfa354SThu Nguyen struct pldm_msgbuf *buf = &_buf; 3162dacfa354SThu Nguyen int rc; 3163dacfa354SThu Nguyen int i; 3164dacfa354SThu Nguyen 3165dacfa354SThu Nguyen if (!pdr) { 3166dacfa354SThu Nguyen return -EINVAL; 3167dacfa354SThu Nguyen } 3168dacfa354SThu Nguyen 3169dacfa354SThu Nguyen if (pdr->name_string_count == 0 && pdr->names) { 3170dacfa354SThu Nguyen return -EINVAL; 3171dacfa354SThu Nguyen } 3172dacfa354SThu Nguyen 3173dacfa354SThu Nguyen if (pdr->name_string_count > 0 && !pdr->names) { 3174dacfa354SThu Nguyen return -EINVAL; 3175dacfa354SThu Nguyen } 3176dacfa354SThu Nguyen 3177dacfa354SThu Nguyen if (pdr->name_string_count == 0) { 3178dacfa354SThu Nguyen return 0; 3179dacfa354SThu Nguyen } 3180dacfa354SThu Nguyen 3181dacfa354SThu Nguyen /* 3182dacfa354SThu Nguyen * Minimum size is one NUL for each member of each entry 3183dacfa354SThu Nguyen * 3184dacfa354SThu Nguyen * Note that the definition of nameLanguageTag in DSP0248 v1.2.2 3185dacfa354SThu Nguyen * states the following: 3186dacfa354SThu Nguyen * 3187dacfa354SThu Nguyen * > A null-terminated ISO646 ASCII string ... 3188dacfa354SThu Nguyen * > 3189dacfa354SThu Nguyen * > special value: null string = 0x0000 = unspecified. 3190dacfa354SThu Nguyen * 3191dacfa354SThu Nguyen * Until proven otherwise we will assume the "0x0000" is a 3192dacfa354SThu Nguyen * misrepresentation of an ASCII NUL, and that ASCII NUL is 3193dacfa354SThu Nguyen * represented by a single byte. 3194dacfa354SThu Nguyen */ 3195dacfa354SThu Nguyen rc = pldm_msgbuf_init_errno( 3196dacfa354SThu Nguyen buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)), 3197dacfa354SThu Nguyen pdr->auxiliary_name_data, pdr->auxiliary_name_data_size); 3198dacfa354SThu Nguyen if (rc) { 3199dacfa354SThu Nguyen return rc; 3200dacfa354SThu Nguyen } 3201dacfa354SThu Nguyen 3202dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3203dacfa354SThu Nguyen void *loc = NULL; 3204dacfa354SThu Nguyen pldm_msgbuf_span_string_utf16(buf, &loc, NULL); 3205dacfa354SThu Nguyen pdr->names[i].name = loc; 3206dacfa354SThu Nguyen } 3207dacfa354SThu Nguyen 3208dacfa354SThu Nguyen for (i = 0; i < pdr->name_string_count; i++) { 3209dacfa354SThu Nguyen void *loc = NULL; 3210dacfa354SThu Nguyen pldm_msgbuf_span_string_ascii(buf, &loc, NULL); 3211dacfa354SThu Nguyen pdr->names[i].tag = loc; 3212dacfa354SThu Nguyen } 3213dacfa354SThu Nguyen 3214dacfa354SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 3215dacfa354SThu Nguyen } 3216a5d18dc7SThu Nguyen 32173559aa1fSThu Nguyen LIBPLDM_ABI_STABLE 321802903038SThu Nguyen int decode_pldm_platform_cper_event(const void *event_data, 321902903038SThu Nguyen size_t event_data_length, 322002903038SThu Nguyen struct pldm_platform_cper_event *cper_event, 322102903038SThu Nguyen size_t cper_event_length) 3222a5d18dc7SThu Nguyen { 3223a5d18dc7SThu Nguyen struct pldm_msgbuf _buf; 3224a5d18dc7SThu Nguyen struct pldm_msgbuf *buf = &_buf; 3225a5d18dc7SThu Nguyen int rc; 3226a5d18dc7SThu Nguyen 3227a5d18dc7SThu Nguyen if (!cper_event || !event_data) { 3228a5d18dc7SThu Nguyen return -EINVAL; 3229a5d18dc7SThu Nguyen } 3230a5d18dc7SThu Nguyen 3231a5d18dc7SThu Nguyen if (cper_event_length < sizeof(*cper_event)) { 3232a5d18dc7SThu Nguyen return -EINVAL; 3233a5d18dc7SThu Nguyen } 3234a5d18dc7SThu Nguyen 3235a5d18dc7SThu Nguyen rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH, 3236a5d18dc7SThu Nguyen event_data, event_data_length); 3237a5d18dc7SThu Nguyen if (rc) { 3238a5d18dc7SThu Nguyen return rc; 3239a5d18dc7SThu Nguyen } 3240a5d18dc7SThu Nguyen 3241a5d18dc7SThu Nguyen pldm_msgbuf_extract(buf, cper_event->format_version); 3242a5d18dc7SThu Nguyen rc = pldm_msgbuf_extract(buf, cper_event->format_type); 3243a5d18dc7SThu Nguyen if (rc) { 3244a5d18dc7SThu Nguyen return rc; 3245a5d18dc7SThu Nguyen } 3246a5d18dc7SThu Nguyen if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER && 3247a5d18dc7SThu Nguyen cper_event->format_type != 3248a5d18dc7SThu Nguyen PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) { 3249a5d18dc7SThu Nguyen return -EPROTO; 3250a5d18dc7SThu Nguyen } 3251a5d18dc7SThu Nguyen 3252a5d18dc7SThu Nguyen rc = pldm_msgbuf_extract(buf, cper_event->event_data_length); 3253a5d18dc7SThu Nguyen if (rc) { 3254a5d18dc7SThu Nguyen return rc; 3255a5d18dc7SThu Nguyen } 3256a5d18dc7SThu Nguyen 3257a5d18dc7SThu Nguyen if (cper_event->event_data_length > 3258a5d18dc7SThu Nguyen (cper_event_length - sizeof(*cper_event))) { 3259a5d18dc7SThu Nguyen return -EOVERFLOW; 3260a5d18dc7SThu Nguyen } 3261a5d18dc7SThu Nguyen 32620a1be3cbSAndrew Jeffery rc = pldm_msgbuf_extract_array_uint8( 32630a1be3cbSAndrew Jeffery buf, cper_event->event_data_length, cper_event->event_data, 32640a1be3cbSAndrew Jeffery cper_event_length - sizeof(*cper_event)); 32650a1be3cbSAndrew Jeffery if (rc) { 32660a1be3cbSAndrew Jeffery return rc; 32670a1be3cbSAndrew Jeffery } 3268a5d18dc7SThu Nguyen 3269a5d18dc7SThu Nguyen return pldm_msgbuf_destroy_consumed(buf); 3270a5d18dc7SThu Nguyen } 3271a5d18dc7SThu Nguyen 32723559aa1fSThu Nguyen LIBPLDM_ABI_STABLE 3273a5d18dc7SThu Nguyen uint8_t * 3274a5d18dc7SThu Nguyen pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event) 3275a5d18dc7SThu Nguyen { 3276a5d18dc7SThu Nguyen return event->event_data; 3277a5d18dc7SThu Nguyen } 3278