blob: 79f5ba5c0ba1340d064c3ad40d56a67ec3d556e1 [file] [log] [blame]
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06001#include <endian.h>
2#include <string.h>
3
4#include "base.h"
5
Tom Joseph41251042019-02-07 16:17:07 +05306int pack_pldm_header(const struct pldm_header_info *hdr,
7 struct pldm_msg_hdr *msg)
8{
9 if (msg == NULL || hdr == NULL) {
10 return PLDM_ERROR_INVALID_DATA;
11 }
12
13 if (hdr->msg_type != PLDM_RESPONSE && hdr->msg_type != PLDM_REQUEST &&
14 hdr->msg_type != PLDM_ASYNC_REQUEST_NOTIFY) {
15 return PLDM_ERROR_INVALID_DATA;
16 }
17
18 if (hdr->instance > PLDM_INSTANCE_MAX) {
19 return PLDM_ERROR_INVALID_DATA;
20 }
21
22 if (hdr->pldm_type > (PLDM_MAX_TYPES - 1)) {
23 return PLDM_ERROR_INVALID_PLDM_TYPE;
24 }
25
26 uint8_t datagram = (hdr->msg_type == PLDM_ASYNC_REQUEST_NOTIFY) ? 1 : 0;
27
28 if (hdr->msg_type == PLDM_RESPONSE) {
29 msg->request = PLDM_RESPONSE;
30 } else if (hdr->msg_type == PLDM_REQUEST ||
31 hdr->msg_type == PLDM_ASYNC_REQUEST_NOTIFY) {
32 msg->request = PLDM_REQUEST;
33 }
34 msg->datagram = datagram;
35 msg->reserved = 0;
36 msg->instance_id = hdr->instance;
Christian Geddes6c146f12020-05-01 14:48:23 -050037 msg->header_ver = PLDM_CURRENT_VERSION;
Tom Joseph41251042019-02-07 16:17:07 +053038 msg->type = hdr->pldm_type;
39 msg->command = hdr->command;
40
41 return PLDM_SUCCESS;
42}
43
44int unpack_pldm_header(const struct pldm_msg_hdr *msg,
45 struct pldm_header_info *hdr)
46{
47 if (msg == NULL) {
48 return PLDM_ERROR_INVALID_DATA;
49 }
50
51 if (msg->request == PLDM_RESPONSE) {
52 hdr->msg_type = PLDM_RESPONSE;
53 } else {
54 hdr->msg_type =
55 msg->datagram ? PLDM_ASYNC_REQUEST_NOTIFY : PLDM_REQUEST;
56 }
57
58 hdr->instance = msg->instance_id;
59 hdr->pldm_type = msg->type;
60 hdr->command = msg->command;
61
62 return PLDM_SUCCESS;
63}
64
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060065int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg)
66{
67 if (msg == NULL) {
68 return PLDM_ERROR_INVALID_DATA;
69 }
70
Deepak Kodihalli67ec4652019-02-16 07:00:48 -060071 struct pldm_header_info header = {0};
72 header.instance = instance_id;
73 header.msg_type = PLDM_REQUEST;
74 header.command = PLDM_GET_PLDM_TYPES;
75 pack_pldm_header(&header, &(msg->hdr));
76
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060077 return PLDM_SUCCESS;
78}
79
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060080int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version,
81 struct pldm_msg *msg)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060082{
83 if (msg == NULL) {
84 return PLDM_ERROR_INVALID_DATA;
85 }
86
Deepak Kodihalli67ec4652019-02-16 07:00:48 -060087 struct pldm_header_info header = {0};
88 header.instance = instance_id;
89 header.msg_type = PLDM_REQUEST;
90 header.command = PLDM_GET_PLDM_COMMANDS;
91 pack_pldm_header(&header, &(msg->hdr));
92
Priyanga4b790ce2019-06-10 01:30:09 -050093 struct pldm_get_commands_req *request =
94 (struct pldm_get_commands_req *)msg->payload;
95
96 request->type = type;
97 request->version = version;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060098
99 return PLDM_SUCCESS;
100}
101
102int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600103 const bitfield8_t *types, struct pldm_msg *msg)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600104{
105 if (msg == NULL) {
106 return PLDM_ERROR_INVALID_DATA;
107 }
108
Priyanga4b790ce2019-06-10 01:30:09 -0500109 struct pldm_get_types_resp *response =
110 (struct pldm_get_types_resp *)msg->payload;
Deepak Kodihalli67ec4652019-02-16 07:00:48 -0600111
Priyanga4b790ce2019-06-10 01:30:09 -0500112 response->completion_code = completion_code;
Deepak Kodihalli67ec4652019-02-16 07:00:48 -0600113 struct pldm_header_info header = {0};
114 header.instance = instance_id;
115 header.msg_type = PLDM_RESPONSE;
116 header.command = PLDM_GET_PLDM_TYPES;
117 pack_pldm_header(&header, &(msg->hdr));
118
Priyanga4b790ce2019-06-10 01:30:09 -0500119 if (response->completion_code == PLDM_SUCCESS) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600120 if (types == NULL) {
121 return PLDM_ERROR_INVALID_DATA;
122 }
Priyanga4b790ce2019-06-10 01:30:09 -0500123 memcpy(response->types, &(types->byte), PLDM_MAX_TYPES / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600124 }
125
126 return PLDM_SUCCESS;
127}
128
Zahed Hossain223a73d2019-07-04 12:46:18 -0500129int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length,
vkaverapa6575b82019-04-03 05:33:52 -0500130 uint8_t *type, ver32_t *version)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600131{
132 if (msg == NULL || type == NULL || version == NULL) {
133 return PLDM_ERROR_INVALID_DATA;
134 }
135
vkaverapa6575b82019-04-03 05:33:52 -0500136 if (payload_length != PLDM_GET_COMMANDS_REQ_BYTES) {
137 return PLDM_ERROR_INVALID_LENGTH;
138 }
139
Priyanga4b790ce2019-06-10 01:30:09 -0500140 struct pldm_get_commands_req *request =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500141 (struct pldm_get_commands_req *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500142 *type = request->type;
143 *version = request->version;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600144 return PLDM_SUCCESS;
145}
146
147int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600148 const bitfield8_t *commands, struct pldm_msg *msg)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600149{
150 if (msg == NULL) {
151 return PLDM_ERROR_INVALID_DATA;
152 }
153
Priyanga4b790ce2019-06-10 01:30:09 -0500154 struct pldm_get_commands_resp *response =
155 (struct pldm_get_commands_resp *)msg->payload;
156 response->completion_code = completion_code;
Deepak Kodihalli67ec4652019-02-16 07:00:48 -0600157
158 struct pldm_header_info header = {0};
159 header.instance = instance_id;
160 header.msg_type = PLDM_RESPONSE;
161 header.command = PLDM_GET_PLDM_COMMANDS;
162 pack_pldm_header(&header, &(msg->hdr));
163
Priyanga4b790ce2019-06-10 01:30:09 -0500164 if (response->completion_code == PLDM_SUCCESS) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600165 if (commands == NULL) {
166 return PLDM_ERROR_INVALID_DATA;
167 }
Priyanga4b790ce2019-06-10 01:30:09 -0500168 memcpy(response->commands, &(commands->byte),
169 PLDM_MAX_CMDS_PER_TYPE / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600170 }
171
172 return PLDM_SUCCESS;
173}
174
Zahed Hossain223a73d2019-07-04 12:46:18 -0500175int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600176 uint8_t *completion_code, bitfield8_t *types)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600177{
vkaverapa6575b82019-04-03 05:33:52 -0500178 if (msg == NULL || types == NULL || completion_code == NULL) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600179 return PLDM_ERROR_INVALID_DATA;
180 }
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600181
George Liu684a7162019-12-06 15:10:52 +0800182 *completion_code = msg->payload[0];
183 if (PLDM_SUCCESS != *completion_code) {
184 return PLDM_SUCCESS;
185 }
186
vkaverapa6575b82019-04-03 05:33:52 -0500187 if (payload_length != PLDM_GET_TYPES_RESP_BYTES) {
188 return PLDM_ERROR_INVALID_LENGTH;
189 }
190
Priyanga4b790ce2019-06-10 01:30:09 -0500191 struct pldm_get_types_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500192 (struct pldm_get_types_resp *)msg->payload;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600193
Priyanga4b790ce2019-06-10 01:30:09 -0500194 memcpy(&(types->byte), response->types, PLDM_MAX_TYPES / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600195
196 return PLDM_SUCCESS;
197}
198
Zahed Hossain223a73d2019-07-04 12:46:18 -0500199int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600200 uint8_t *completion_code, bitfield8_t *commands)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600201{
vkaverapa6575b82019-04-03 05:33:52 -0500202 if (msg == NULL || commands == NULL || completion_code == NULL) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600203 return PLDM_ERROR_INVALID_DATA;
204 }
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600205
George Liu684a7162019-12-06 15:10:52 +0800206 *completion_code = msg->payload[0];
207 if (PLDM_SUCCESS != *completion_code) {
208 return PLDM_SUCCESS;
209 }
210
vkaverapa6575b82019-04-03 05:33:52 -0500211 if (payload_length != PLDM_GET_COMMANDS_RESP_BYTES) {
212 return PLDM_ERROR_INVALID_LENGTH;
213 }
214
Priyanga4b790ce2019-06-10 01:30:09 -0500215 struct pldm_get_commands_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500216 (struct pldm_get_commands_resp *)msg->payload;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600217
Priyanga4b790ce2019-06-10 01:30:09 -0500218 memcpy(&(commands->byte), response->commands,
vkaverapa6575b82019-04-03 05:33:52 -0500219 PLDM_MAX_CMDS_PER_TYPE / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600220
221 return PLDM_SUCCESS;
222}
Sampa Misra432e1872019-02-13 03:49:43 -0600223
224int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
225 uint8_t transfer_opflag, uint8_t type,
226 struct pldm_msg *msg)
227{
228 struct pldm_header_info header = {0};
229 int rc = PLDM_SUCCESS;
230
231 if (NULL == msg) {
232 return PLDM_ERROR_INVALID_DATA;
233 }
234
235 header.msg_type = PLDM_REQUEST;
236 header.instance = instance_id;
237 header.pldm_type = PLDM_BASE;
238 header.command = PLDM_GET_PLDM_VERSION;
239
240 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
241 return rc;
242 }
243
Priyanga4b790ce2019-06-10 01:30:09 -0500244 struct pldm_get_version_req *request =
245 (struct pldm_get_version_req *)msg->payload;
Sampa Misra432e1872019-02-13 03:49:43 -0600246 transfer_handle = htole32(transfer_handle);
Priyanga4b790ce2019-06-10 01:30:09 -0500247 request->transfer_handle = transfer_handle;
248 request->transfer_opflag = transfer_opflag;
249 request->type = type;
Sampa Misra432e1872019-02-13 03:49:43 -0600250
251 return PLDM_SUCCESS;
252}
253
254int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
255 uint32_t next_transfer_handle,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600256 uint8_t transfer_flag, const ver32_t *version_data,
Sampa Misra432e1872019-02-13 03:49:43 -0600257 size_t version_size, struct pldm_msg *msg)
258{
259 struct pldm_header_info header = {0};
260 int rc = PLDM_SUCCESS;
Priyanga4b790ce2019-06-10 01:30:09 -0500261 struct pldm_get_version_resp *response =
262 (struct pldm_get_version_resp *)msg->payload;
263 response->completion_code = completion_code;
264 if (response->completion_code == PLDM_SUCCESS) {
Sampa Misra432e1872019-02-13 03:49:43 -0600265
266 header.msg_type = PLDM_RESPONSE;
267 header.instance = instance_id;
268 header.pldm_type = PLDM_BASE;
269 header.command = PLDM_GET_PLDM_VERSION;
270
271 if ((rc = pack_pldm_header(&header, &(msg->hdr))) >
272 PLDM_SUCCESS) {
273 return rc;
274 }
Priyanga4b790ce2019-06-10 01:30:09 -0500275 response->next_transfer_handle = htole32(next_transfer_handle);
276 response->transfer_flag = transfer_flag;
277 memcpy(response->version_data, (uint8_t *)version_data,
278 version_size);
Sampa Misra432e1872019-02-13 03:49:43 -0600279 }
280 return PLDM_SUCCESS;
281}
282
Zahed Hossain223a73d2019-07-04 12:46:18 -0500283int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length,
Sampa Misra432e1872019-02-13 03:49:43 -0600284 uint32_t *transfer_handle, uint8_t *transfer_opflag,
285 uint8_t *type)
286{
vkaverapa6575b82019-04-03 05:33:52 -0500287
288 if (payload_length != PLDM_GET_VERSION_REQ_BYTES) {
289 return PLDM_ERROR_INVALID_LENGTH;
290 }
291
Priyanga4b790ce2019-06-10 01:30:09 -0500292 struct pldm_get_version_req *request =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500293 (struct pldm_get_version_req *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500294 *transfer_handle = le32toh(request->transfer_handle);
295 *transfer_opflag = request->transfer_opflag;
296 *type = request->type;
Sampa Misra432e1872019-02-13 03:49:43 -0600297 return PLDM_SUCCESS;
298}
299
Zahed Hossain223a73d2019-07-04 12:46:18 -0500300int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600301 uint8_t *completion_code,
Sampa Misra432e1872019-02-13 03:49:43 -0600302 uint32_t *next_transfer_handle,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600303 uint8_t *transfer_flag, ver32_t *version)
Sampa Misra432e1872019-02-13 03:49:43 -0600304{
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600305 if (msg == NULL || next_transfer_handle == NULL ||
vkaverapa6575b82019-04-03 05:33:52 -0500306 transfer_flag == NULL || completion_code == NULL) {
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600307 return PLDM_ERROR_INVALID_DATA;
308 }
309
George Liu684a7162019-12-06 15:10:52 +0800310 *completion_code = msg->payload[0];
311 if (PLDM_SUCCESS != *completion_code) {
312 return PLDM_SUCCESS;
313 }
314
vkaverapa6575b82019-04-03 05:33:52 -0500315 if (payload_length < PLDM_GET_VERSION_RESP_BYTES) {
316 return PLDM_ERROR_INVALID_LENGTH;
317 }
318
Priyanga4b790ce2019-06-10 01:30:09 -0500319 struct pldm_get_version_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500320 (struct pldm_get_version_resp *)msg->payload;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600321
Priyanga4b790ce2019-06-10 01:30:09 -0500322 *next_transfer_handle = le32toh(response->next_transfer_handle);
323 *transfer_flag = response->transfer_flag;
324 memcpy(version, (uint8_t *)response->version_data, sizeof(ver32_t));
Sampa Misra432e1872019-02-13 03:49:43 -0600325
326 return PLDM_SUCCESS;
327}
John Wang5c4f80d2019-07-29 11:12:18 +0800328
Sridevi Rameshbc6ff262019-12-12 04:58:35 -0600329int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg)
330{
331 if (msg == NULL) {
332 return PLDM_ERROR_INVALID_DATA;
333 }
334
335 struct pldm_header_info header = {0};
336 header.instance = instance_id;
337 header.msg_type = PLDM_REQUEST;
338 header.command = PLDM_GET_TID;
339 pack_pldm_header(&header, &(msg->hdr));
340
341 return PLDM_SUCCESS;
342}
John Wang5c4f80d2019-07-29 11:12:18 +0800343int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code,
344 uint8_t tid, struct pldm_msg *msg)
345{
346 if (msg == NULL) {
347 return PLDM_ERROR_INVALID_DATA;
348 }
349
350 struct pldm_get_tid_resp *response =
351 (struct pldm_get_tid_resp *)msg->payload;
352
353 response->completion_code = completion_code;
354 struct pldm_header_info header = {0};
355 header.instance = instance_id;
356 header.msg_type = PLDM_RESPONSE;
357 header.command = PLDM_GET_TID;
358 pack_pldm_header(&header, &(msg->hdr));
359
360 response->tid = tid;
361
362 return PLDM_SUCCESS;
363}
364
365int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length,
366 uint8_t *completion_code, uint8_t *tid)
367{
368 if (msg == NULL || tid == NULL || completion_code == NULL) {
369 return PLDM_ERROR_INVALID_DATA;
370 }
371
George Liu684a7162019-12-06 15:10:52 +0800372 *completion_code = msg->payload[0];
373 if (PLDM_SUCCESS != *completion_code) {
374 return PLDM_SUCCESS;
375 }
376
John Wang5c4f80d2019-07-29 11:12:18 +0800377 if (payload_length != PLDM_GET_TID_RESP_BYTES) {
378 return PLDM_ERROR_INVALID_LENGTH;
379 }
380
381 struct pldm_get_tid_resp *response =
382 (struct pldm_get_tid_resp *)msg->payload;
John Wang5c4f80d2019-07-29 11:12:18 +0800383
384 *tid = response->tid;
385
386 return PLDM_SUCCESS;
387}
John Wang7f02d702019-12-03 13:38:14 +0800388
389int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command,
390 uint8_t cc, struct pldm_msg *msg)
391{
392 struct pldm_header_info header = {0};
393
394 if (msg == NULL) {
395 return PLDM_ERROR_INVALID_DATA;
396 }
397
398 header.instance = instance_id;
399 header.msg_type = PLDM_RESPONSE;
400 header.pldm_type = type;
401 header.command = command;
402 int rc = pack_pldm_header(&header, &msg->hdr);
403 if (rc != PLDM_SUCCESS) {
404 return rc;
405 }
406
407 msg->payload[0] = cc;
408
409 return PLDM_SUCCESS;
410}