blob: f28231b08aa5ffcbc7d9ea7b9f28ca08313e74a7 [file] [log] [blame]
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +05301#include <endian.h>
2#include <string.h>
3
4#include "fru.h"
5
6int encode_get_fru_record_table_metadata_req(uint8_t instance_id,
7 struct pldm_msg *msg)
8{
9 if (msg == NULL) {
10 return PLDM_ERROR_INVALID_DATA;
11 }
12
13 struct pldm_header_info header = {0};
14 header.instance = instance_id;
15 header.msg_type = PLDM_REQUEST;
16 header.pldm_type = PLDM_FRU;
17 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
18 int rc = pack_pldm_header(&header, &(msg->hdr));
19 if (PLDM_SUCCESS != rc) {
20 return rc;
21 }
22 return PLDM_SUCCESS;
23}
24
25int decode_get_fru_record_table_metadata_resp(
26 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
27 uint8_t *fru_data_major_version, uint8_t *fru_data_minor_version,
28 uint32_t *fru_table_maximum_size, uint32_t *fru_table_length,
29 uint16_t *total_record_set_identifiers, uint16_t *total_table_records,
30 uint32_t *checksum)
31{
32 if (msg == NULL || completion_code == NULL ||
33 fru_data_major_version == NULL || fru_data_minor_version == NULL ||
34 fru_table_maximum_size == NULL || fru_table_length == NULL ||
35 total_record_set_identifiers == NULL ||
36 total_table_records == NULL || checksum == NULL) {
37 return PLDM_ERROR_INVALID_DATA;
38 }
39
George Liu684a7162019-12-06 15:10:52 +080040 *completion_code = msg->payload[0];
41 if (PLDM_SUCCESS != *completion_code) {
42 return PLDM_SUCCESS;
43 }
44
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053045 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES) {
46 return PLDM_ERROR_INVALID_LENGTH;
47 }
48
49 struct pldm_get_fru_record_table_metadata_resp *response =
50 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053051
52 *fru_data_major_version = response->fru_data_major_version;
53 *fru_data_minor_version = response->fru_data_minor_version;
54 *fru_table_maximum_size = le32toh(response->fru_table_maximum_size);
55 *fru_table_length = le32toh(response->fru_table_length);
56 *total_record_set_identifiers =
57 le16toh(response->total_record_set_identifiers);
58 *total_table_records = le16toh(response->total_table_records);
59 *checksum = le32toh(response->checksum);
60
61 return PLDM_SUCCESS;
62}
63
64int encode_get_fru_record_table_metadata_resp(
65 uint8_t instance_id, uint8_t completion_code,
66 uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
67 uint32_t fru_table_maximum_size, uint32_t fru_table_length,
68 uint16_t total_record_set_identifiers, uint16_t total_table_records,
69 uint32_t checksum, struct pldm_msg *msg)
70{
71
72 if (msg == NULL) {
73 return PLDM_ERROR_INVALID_DATA;
74 }
75
76 struct pldm_header_info header = {0};
77 header.msg_type = PLDM_RESPONSE;
78 header.instance = instance_id;
79 header.pldm_type = PLDM_FRU;
80 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
81 int rc = pack_pldm_header(&header, &(msg->hdr));
82 if (PLDM_SUCCESS != rc) {
83 return rc;
84 }
85
86 struct pldm_get_fru_record_table_metadata_resp *response =
87 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
88 response->completion_code = completion_code;
89 if (response->completion_code == PLDM_SUCCESS) {
90 response->fru_data_major_version = fru_data_major_version;
91 response->fru_data_minor_version = fru_data_minor_version;
92 response->fru_table_maximum_size =
93 htole32(fru_table_maximum_size);
94 response->fru_table_length = htole32(fru_table_length);
95 response->total_record_set_identifiers =
96 htole16(total_record_set_identifiers);
97 response->total_table_records = htole16(total_table_records);
98 response->checksum = htole32(checksum);
99 }
100
101 return PLDM_SUCCESS;
102}
PriyangaRamasamy497665a2019-07-30 12:48:25 +0530103
104int decode_get_fru_record_table_req(const struct pldm_msg *msg,
105 size_t payload_length,
106 uint32_t *data_transfer_handle,
107 uint8_t *transfer_operation_flag)
108{
109 if (msg == NULL || data_transfer_handle == NULL ||
110 transfer_operation_flag == NULL) {
111 return PLDM_ERROR_INVALID_DATA;
112 }
113
114 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES) {
115 return PLDM_ERROR_INVALID_LENGTH;
116 }
117
118 struct pldm_get_fru_record_table_req *req =
119 (struct pldm_get_fru_record_table_req *)msg->payload;
120
121 *data_transfer_handle = le32toh(req->data_transfer_handle);
122 *transfer_operation_flag = req->transfer_operation_flag;
123
124 return PLDM_SUCCESS;
125}
126
127int encode_get_fru_record_table_resp(uint8_t instance_id,
128 uint8_t completion_code,
129 uint32_t next_data_transfer_handle,
130 uint8_t transfer_flag,
131 struct pldm_msg *msg)
132{
133 struct pldm_header_info header = {0};
134 int rc = PLDM_ERROR_INVALID_DATA;
135
136 header.msg_type = PLDM_RESPONSE;
137 header.instance = instance_id;
138 header.pldm_type = PLDM_FRU;
139 header.command = PLDM_GET_FRU_RECORD_TABLE;
140
141 if (msg == NULL) {
142 return rc;
143 }
144
145 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
146 return rc;
147 }
148
149 struct pldm_get_fru_record_table_resp *resp =
150 (struct pldm_get_fru_record_table_resp *)msg->payload;
151
152 resp->completion_code = completion_code;
153
154 if (resp->completion_code == PLDM_SUCCESS) {
155
156 resp->next_data_transfer_handle =
157 htole32(next_data_transfer_handle);
158 resp->transfer_flag = transfer_flag;
159 }
160
161 return PLDM_SUCCESS;
162}
Tom Joseph93d68712020-01-07 10:24:41 +0530163
164int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size,
165 uint16_t record_set_id, uint8_t record_type,
166 uint8_t num_frus, uint8_t encoding, uint8_t *tlvs,
167 size_t tlvs_size)
168{
169 size_t record_hdr_size = sizeof(struct pldm_fru_record_data_format) -
170 sizeof(struct pldm_fru_record_tlv);
171
172 if ((*curr_size + record_hdr_size + tlvs_size) != total_size) {
173 return PLDM_ERROR_INVALID_LENGTH;
174 }
175
176 if (fru_table == NULL || curr_size == NULL || !tlvs_size) {
177 return PLDM_ERROR_INVALID_DATA;
178 }
179
180 struct pldm_fru_record_data_format *record =
181 (struct pldm_fru_record_data_format *)(fru_table + *curr_size);
182 record->record_set_id = htole16(record_set_id);
183 record->record_type = record_type;
184 record->num_fru_fields = num_frus;
185 record->encoding_type = encoding;
186 *curr_size += record_hdr_size;
187
188 if (tlvs) {
189 memcpy(fru_table + *curr_size, tlvs, tlvs_size);
190 *curr_size += tlvs_size;
191 }
192
193 return PLDM_SUCCESS;
194}