blob: 242fc288ec224f832e35accdd7e2859c14288596 [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,
Christian Geddes3bdb3c22020-05-01 14:55:39 -05007 struct pldm_msg *msg,
8 size_t payload_length)
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +05309{
10 if (msg == NULL) {
11 return PLDM_ERROR_INVALID_DATA;
12 }
13
Christian Geddes3bdb3c22020-05-01 14:55:39 -050014 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES) {
15 return PLDM_ERROR_INVALID_LENGTH;
16 }
17
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053018 struct pldm_header_info header = {0};
19 header.instance = instance_id;
20 header.msg_type = PLDM_REQUEST;
21 header.pldm_type = PLDM_FRU;
22 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
23 int rc = pack_pldm_header(&header, &(msg->hdr));
24 if (PLDM_SUCCESS != rc) {
25 return rc;
26 }
Christian Geddes3bdb3c22020-05-01 14:55:39 -050027
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053028 return PLDM_SUCCESS;
29}
30
31int decode_get_fru_record_table_metadata_resp(
32 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
33 uint8_t *fru_data_major_version, uint8_t *fru_data_minor_version,
34 uint32_t *fru_table_maximum_size, uint32_t *fru_table_length,
35 uint16_t *total_record_set_identifiers, uint16_t *total_table_records,
36 uint32_t *checksum)
37{
38 if (msg == NULL || completion_code == NULL ||
39 fru_data_major_version == NULL || fru_data_minor_version == NULL ||
40 fru_table_maximum_size == NULL || fru_table_length == NULL ||
41 total_record_set_identifiers == NULL ||
42 total_table_records == NULL || checksum == NULL) {
43 return PLDM_ERROR_INVALID_DATA;
44 }
45
George Liu684a7162019-12-06 15:10:52 +080046 *completion_code = msg->payload[0];
47 if (PLDM_SUCCESS != *completion_code) {
48 return PLDM_SUCCESS;
49 }
50
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053051 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES) {
52 return PLDM_ERROR_INVALID_LENGTH;
53 }
54
55 struct pldm_get_fru_record_table_metadata_resp *response =
56 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053057
58 *fru_data_major_version = response->fru_data_major_version;
59 *fru_data_minor_version = response->fru_data_minor_version;
60 *fru_table_maximum_size = le32toh(response->fru_table_maximum_size);
61 *fru_table_length = le32toh(response->fru_table_length);
62 *total_record_set_identifiers =
63 le16toh(response->total_record_set_identifiers);
64 *total_table_records = le16toh(response->total_table_records);
65 *checksum = le32toh(response->checksum);
66
67 return PLDM_SUCCESS;
68}
69
70int encode_get_fru_record_table_metadata_resp(
71 uint8_t instance_id, uint8_t completion_code,
72 uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
73 uint32_t fru_table_maximum_size, uint32_t fru_table_length,
74 uint16_t total_record_set_identifiers, uint16_t total_table_records,
75 uint32_t checksum, struct pldm_msg *msg)
76{
77
78 if (msg == NULL) {
79 return PLDM_ERROR_INVALID_DATA;
80 }
81
82 struct pldm_header_info header = {0};
83 header.msg_type = PLDM_RESPONSE;
84 header.instance = instance_id;
85 header.pldm_type = PLDM_FRU;
86 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
87 int rc = pack_pldm_header(&header, &(msg->hdr));
88 if (PLDM_SUCCESS != rc) {
89 return rc;
90 }
91
92 struct pldm_get_fru_record_table_metadata_resp *response =
93 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
94 response->completion_code = completion_code;
95 if (response->completion_code == PLDM_SUCCESS) {
96 response->fru_data_major_version = fru_data_major_version;
97 response->fru_data_minor_version = fru_data_minor_version;
98 response->fru_table_maximum_size =
99 htole32(fru_table_maximum_size);
100 response->fru_table_length = htole32(fru_table_length);
101 response->total_record_set_identifiers =
102 htole16(total_record_set_identifiers);
103 response->total_table_records = htole16(total_table_records);
104 response->checksum = htole32(checksum);
105 }
106
107 return PLDM_SUCCESS;
108}
PriyangaRamasamy497665a2019-07-30 12:48:25 +0530109
110int decode_get_fru_record_table_req(const struct pldm_msg *msg,
111 size_t payload_length,
112 uint32_t *data_transfer_handle,
113 uint8_t *transfer_operation_flag)
114{
115 if (msg == NULL || data_transfer_handle == NULL ||
116 transfer_operation_flag == NULL) {
117 return PLDM_ERROR_INVALID_DATA;
118 }
119
120 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES) {
121 return PLDM_ERROR_INVALID_LENGTH;
122 }
123
124 struct pldm_get_fru_record_table_req *req =
125 (struct pldm_get_fru_record_table_req *)msg->payload;
126
127 *data_transfer_handle = le32toh(req->data_transfer_handle);
128 *transfer_operation_flag = req->transfer_operation_flag;
129
130 return PLDM_SUCCESS;
131}
132
133int encode_get_fru_record_table_resp(uint8_t instance_id,
134 uint8_t completion_code,
135 uint32_t next_data_transfer_handle,
136 uint8_t transfer_flag,
137 struct pldm_msg *msg)
138{
139 struct pldm_header_info header = {0};
140 int rc = PLDM_ERROR_INVALID_DATA;
141
142 header.msg_type = PLDM_RESPONSE;
143 header.instance = instance_id;
144 header.pldm_type = PLDM_FRU;
145 header.command = PLDM_GET_FRU_RECORD_TABLE;
146
147 if (msg == NULL) {
148 return rc;
149 }
150
151 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
152 return rc;
153 }
154
155 struct pldm_get_fru_record_table_resp *resp =
156 (struct pldm_get_fru_record_table_resp *)msg->payload;
157
158 resp->completion_code = completion_code;
159
160 if (resp->completion_code == PLDM_SUCCESS) {
161
162 resp->next_data_transfer_handle =
163 htole32(next_data_transfer_handle);
164 resp->transfer_flag = transfer_flag;
165 }
166
167 return PLDM_SUCCESS;
168}
Tom Joseph93d68712020-01-07 10:24:41 +0530169
170int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size,
171 uint16_t record_set_id, uint8_t record_type,
172 uint8_t num_frus, uint8_t encoding, uint8_t *tlvs,
173 size_t tlvs_size)
174{
175 size_t record_hdr_size = sizeof(struct pldm_fru_record_data_format) -
176 sizeof(struct pldm_fru_record_tlv);
177
178 if ((*curr_size + record_hdr_size + tlvs_size) != total_size) {
179 return PLDM_ERROR_INVALID_LENGTH;
180 }
181
182 if (fru_table == NULL || curr_size == NULL || !tlvs_size) {
183 return PLDM_ERROR_INVALID_DATA;
184 }
185
186 struct pldm_fru_record_data_format *record =
187 (struct pldm_fru_record_data_format *)(fru_table + *curr_size);
188 record->record_set_id = htole16(record_set_id);
189 record->record_type = record_type;
190 record->num_fru_fields = num_frus;
191 record->encoding_type = encoding;
192 *curr_size += record_hdr_size;
193
194 if (tlvs) {
195 memcpy(fru_table + *curr_size, tlvs, tlvs_size);
196 *curr_size += tlvs_size;
197 }
198
199 return PLDM_SUCCESS;
200}
PriyangaRamasamyf3295be2019-07-23 12:18:40 +0530201
202int encode_get_fru_record_table_req(uint8_t instance_id,
203 uint32_t data_transfer_handle,
204 uint8_t transfer_operation_flag,
205 struct pldm_msg *msg, size_t payload_length)
206
207{
208 struct pldm_header_info header = {0};
209 int rc = PLDM_ERROR_INVALID_DATA;
210
211 header.msg_type = PLDM_REQUEST;
212 header.instance = instance_id;
213 header.pldm_type = PLDM_FRU;
214 header.command = PLDM_GET_FRU_RECORD_TABLE;
215
216 if (msg == NULL) {
217 return rc;
218 }
219 if (payload_length != sizeof(struct pldm_get_fru_record_table_req)) {
220 return PLDM_ERROR_INVALID_LENGTH;
221 }
222 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
223 return rc;
224 }
225
226 struct pldm_get_fru_record_table_req *req =
227 (struct pldm_get_fru_record_table_req *)msg->payload;
228 req->data_transfer_handle = htole32(data_transfer_handle);
229 req->transfer_operation_flag = transfer_operation_flag;
230
231 return PLDM_SUCCESS;
232}
233
234int decode_get_fru_record_table_resp(
235 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
236 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
237 uint8_t *fru_record_table_data, size_t *fru_record_table_length)
238{
239 if (msg == NULL || completion_code == NULL ||
240 next_data_transfer_handle == NULL || transfer_flag == NULL ||
241 fru_record_table_data == NULL || fru_record_table_length == NULL) {
242 return PLDM_ERROR_INVALID_DATA;
243 }
244
245 *completion_code = msg->payload[0];
246 if (PLDM_SUCCESS != *completion_code) {
247 return PLDM_SUCCESS;
248 }
249 if (payload_length <= PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES) {
250 return PLDM_ERROR_INVALID_LENGTH;
251 }
252
253 struct pldm_get_fru_record_table_resp *resp =
254 (struct pldm_get_fru_record_table_resp *)msg->payload;
255
256 *next_data_transfer_handle = le32toh(resp->next_data_transfer_handle);
257 *transfer_flag = resp->transfer_flag;
258 memcpy(fru_record_table_data, resp->fru_record_table_data,
259 payload_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES);
260 *fru_record_table_length =
261 payload_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES;
262
263 return PLDM_SUCCESS;
264}