blob: 83cd22ae494be0af09d628438842fa1ba5cb9cb5 [file] [log] [blame]
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06001#include <endian.h>
2#include <string.h>
3
4#include "base.h"
5
George Liub7095ff2021-06-14 16:01:57 +08006uint8_t pack_pldm_header(const struct pldm_header_info *hdr,
7 struct pldm_msg_hdr *msg)
Tom Joseph41251042019-02-07 16:17:07 +05308{
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
George Liub7095ff2021-06-14 16:01:57 +080044uint8_t unpack_pldm_header(const struct pldm_msg_hdr *msg,
45 struct pldm_header_info *hdr)
Tom Joseph41251042019-02-07 16:17:07 +053046{
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;
Deepak Kodihalli67ec4652019-02-16 07:00:48 -060075
George Liub7095ff2021-06-14 16:01:57 +080076 return pack_pldm_header(&header, &(msg->hdr));
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060077}
78
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060079int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version,
80 struct pldm_msg *msg)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060081{
82 if (msg == NULL) {
83 return PLDM_ERROR_INVALID_DATA;
84 }
85
Deepak Kodihalli67ec4652019-02-16 07:00:48 -060086 struct pldm_header_info header = {0};
87 header.instance = instance_id;
88 header.msg_type = PLDM_REQUEST;
89 header.command = PLDM_GET_PLDM_COMMANDS;
George Liub7095ff2021-06-14 16:01:57 +080090
91 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
92 if (rc != PLDM_SUCCESS) {
93 return rc;
94 }
Deepak Kodihalli67ec4652019-02-16 07:00:48 -060095
Priyanga4b790ce2019-06-10 01:30:09 -050096 struct pldm_get_commands_req *request =
97 (struct pldm_get_commands_req *)msg->payload;
98
99 request->type = type;
100 request->version = version;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600101
102 return PLDM_SUCCESS;
103}
104
105int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600106 const bitfield8_t *types, struct pldm_msg *msg)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600107{
108 if (msg == NULL) {
109 return PLDM_ERROR_INVALID_DATA;
110 }
111
Deepak Kodihalli67ec4652019-02-16 07:00:48 -0600112 struct pldm_header_info header = {0};
113 header.instance = instance_id;
114 header.msg_type = PLDM_RESPONSE;
115 header.command = PLDM_GET_PLDM_TYPES;
Deepak Kodihalli67ec4652019-02-16 07:00:48 -0600116
George Liub7095ff2021-06-14 16:01:57 +0800117 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
118 if (rc != PLDM_SUCCESS) {
119 return rc;
120 }
121
122 struct pldm_get_types_resp *response =
123 (struct pldm_get_types_resp *)msg->payload;
124 response->completion_code = completion_code;
Priyanga4b790ce2019-06-10 01:30:09 -0500125 if (response->completion_code == PLDM_SUCCESS) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600126 if (types == NULL) {
127 return PLDM_ERROR_INVALID_DATA;
128 }
Priyanga4b790ce2019-06-10 01:30:09 -0500129 memcpy(response->types, &(types->byte), PLDM_MAX_TYPES / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600130 }
131
132 return PLDM_SUCCESS;
133}
134
Zahed Hossain223a73d2019-07-04 12:46:18 -0500135int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length,
vkaverapa6575b82019-04-03 05:33:52 -0500136 uint8_t *type, ver32_t *version)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600137{
138 if (msg == NULL || type == NULL || version == NULL) {
139 return PLDM_ERROR_INVALID_DATA;
140 }
141
vkaverapa6575b82019-04-03 05:33:52 -0500142 if (payload_length != PLDM_GET_COMMANDS_REQ_BYTES) {
143 return PLDM_ERROR_INVALID_LENGTH;
144 }
145
Priyanga4b790ce2019-06-10 01:30:09 -0500146 struct pldm_get_commands_req *request =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500147 (struct pldm_get_commands_req *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500148 *type = request->type;
149 *version = request->version;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600150 return PLDM_SUCCESS;
151}
152
153int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600154 const bitfield8_t *commands, struct pldm_msg *msg)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600155{
156 if (msg == NULL) {
157 return PLDM_ERROR_INVALID_DATA;
158 }
159
Deepak Kodihalli67ec4652019-02-16 07:00:48 -0600160 struct pldm_header_info header = {0};
161 header.instance = instance_id;
162 header.msg_type = PLDM_RESPONSE;
163 header.command = PLDM_GET_PLDM_COMMANDS;
George Liub7095ff2021-06-14 16:01:57 +0800164 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
165 if (rc != PLDM_SUCCESS) {
166 return rc;
167 }
Deepak Kodihalli67ec4652019-02-16 07:00:48 -0600168
George Liub7095ff2021-06-14 16:01:57 +0800169 struct pldm_get_commands_resp *response =
170 (struct pldm_get_commands_resp *)msg->payload;
171 response->completion_code = completion_code;
Priyanga4b790ce2019-06-10 01:30:09 -0500172 if (response->completion_code == PLDM_SUCCESS) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600173 if (commands == NULL) {
174 return PLDM_ERROR_INVALID_DATA;
175 }
Priyanga4b790ce2019-06-10 01:30:09 -0500176 memcpy(response->commands, &(commands->byte),
177 PLDM_MAX_CMDS_PER_TYPE / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600178 }
179
180 return PLDM_SUCCESS;
181}
182
Zahed Hossain223a73d2019-07-04 12:46:18 -0500183int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600184 uint8_t *completion_code, bitfield8_t *types)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600185{
vkaverapa6575b82019-04-03 05:33:52 -0500186 if (msg == NULL || types == NULL || completion_code == NULL) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600187 return PLDM_ERROR_INVALID_DATA;
188 }
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600189
George Liu684a7162019-12-06 15:10:52 +0800190 *completion_code = msg->payload[0];
191 if (PLDM_SUCCESS != *completion_code) {
192 return PLDM_SUCCESS;
193 }
194
vkaverapa6575b82019-04-03 05:33:52 -0500195 if (payload_length != PLDM_GET_TYPES_RESP_BYTES) {
196 return PLDM_ERROR_INVALID_LENGTH;
197 }
198
Priyanga4b790ce2019-06-10 01:30:09 -0500199 struct pldm_get_types_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500200 (struct pldm_get_types_resp *)msg->payload;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600201
Priyanga4b790ce2019-06-10 01:30:09 -0500202 memcpy(&(types->byte), response->types, PLDM_MAX_TYPES / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600203
204 return PLDM_SUCCESS;
205}
206
Zahed Hossain223a73d2019-07-04 12:46:18 -0500207int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600208 uint8_t *completion_code, bitfield8_t *commands)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600209{
vkaverapa6575b82019-04-03 05:33:52 -0500210 if (msg == NULL || commands == NULL || completion_code == NULL) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600211 return PLDM_ERROR_INVALID_DATA;
212 }
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600213
George Liu684a7162019-12-06 15:10:52 +0800214 *completion_code = msg->payload[0];
215 if (PLDM_SUCCESS != *completion_code) {
216 return PLDM_SUCCESS;
217 }
218
vkaverapa6575b82019-04-03 05:33:52 -0500219 if (payload_length != PLDM_GET_COMMANDS_RESP_BYTES) {
220 return PLDM_ERROR_INVALID_LENGTH;
221 }
222
Priyanga4b790ce2019-06-10 01:30:09 -0500223 struct pldm_get_commands_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500224 (struct pldm_get_commands_resp *)msg->payload;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600225
Priyanga4b790ce2019-06-10 01:30:09 -0500226 memcpy(&(commands->byte), response->commands,
vkaverapa6575b82019-04-03 05:33:52 -0500227 PLDM_MAX_CMDS_PER_TYPE / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600228
229 return PLDM_SUCCESS;
230}
Sampa Misra432e1872019-02-13 03:49:43 -0600231
232int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
233 uint8_t transfer_opflag, uint8_t type,
234 struct pldm_msg *msg)
235{
Sampa Misra432e1872019-02-13 03:49:43 -0600236 if (NULL == msg) {
237 return PLDM_ERROR_INVALID_DATA;
238 }
239
George Liub7095ff2021-06-14 16:01:57 +0800240 struct pldm_header_info header = {0};
Sampa Misra432e1872019-02-13 03:49:43 -0600241 header.msg_type = PLDM_REQUEST;
242 header.instance = instance_id;
243 header.pldm_type = PLDM_BASE;
244 header.command = PLDM_GET_PLDM_VERSION;
245
George Liub7095ff2021-06-14 16:01:57 +0800246 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
247 if (rc != PLDM_SUCCESS) {
Sampa Misra432e1872019-02-13 03:49:43 -0600248 return rc;
249 }
250
Priyanga4b790ce2019-06-10 01:30:09 -0500251 struct pldm_get_version_req *request =
252 (struct pldm_get_version_req *)msg->payload;
Sampa Misra432e1872019-02-13 03:49:43 -0600253 transfer_handle = htole32(transfer_handle);
Priyanga4b790ce2019-06-10 01:30:09 -0500254 request->transfer_handle = transfer_handle;
255 request->transfer_opflag = transfer_opflag;
256 request->type = type;
Sampa Misra432e1872019-02-13 03:49:43 -0600257
258 return PLDM_SUCCESS;
259}
260
261int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
262 uint32_t next_transfer_handle,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600263 uint8_t transfer_flag, const ver32_t *version_data,
Sampa Misra432e1872019-02-13 03:49:43 -0600264 size_t version_size, struct pldm_msg *msg)
265{
George Liub7095ff2021-06-14 16:01:57 +0800266 if (NULL == msg) {
267 return PLDM_ERROR_INVALID_DATA;
268 }
269
Sampa Misra432e1872019-02-13 03:49:43 -0600270 struct pldm_header_info header = {0};
George Liub7095ff2021-06-14 16:01:57 +0800271 header.msg_type = PLDM_RESPONSE;
272 header.instance = instance_id;
273 header.pldm_type = PLDM_BASE;
274 header.command = PLDM_GET_PLDM_VERSION;
275
276 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
277 if (rc != PLDM_SUCCESS) {
278 return rc;
279 }
280
Priyanga4b790ce2019-06-10 01:30:09 -0500281 struct pldm_get_version_resp *response =
282 (struct pldm_get_version_resp *)msg->payload;
283 response->completion_code = completion_code;
284 if (response->completion_code == PLDM_SUCCESS) {
Priyanga4b790ce2019-06-10 01:30:09 -0500285 response->next_transfer_handle = htole32(next_transfer_handle);
286 response->transfer_flag = transfer_flag;
287 memcpy(response->version_data, (uint8_t *)version_data,
288 version_size);
Sampa Misra432e1872019-02-13 03:49:43 -0600289 }
290 return PLDM_SUCCESS;
291}
292
Zahed Hossain223a73d2019-07-04 12:46:18 -0500293int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length,
Sampa Misra432e1872019-02-13 03:49:43 -0600294 uint32_t *transfer_handle, uint8_t *transfer_opflag,
295 uint8_t *type)
296{
vkaverapa6575b82019-04-03 05:33:52 -0500297
298 if (payload_length != PLDM_GET_VERSION_REQ_BYTES) {
299 return PLDM_ERROR_INVALID_LENGTH;
300 }
301
Priyanga4b790ce2019-06-10 01:30:09 -0500302 struct pldm_get_version_req *request =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500303 (struct pldm_get_version_req *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500304 *transfer_handle = le32toh(request->transfer_handle);
305 *transfer_opflag = request->transfer_opflag;
306 *type = request->type;
Sampa Misra432e1872019-02-13 03:49:43 -0600307 return PLDM_SUCCESS;
308}
309
Zahed Hossain223a73d2019-07-04 12:46:18 -0500310int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600311 uint8_t *completion_code,
Sampa Misra432e1872019-02-13 03:49:43 -0600312 uint32_t *next_transfer_handle,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600313 uint8_t *transfer_flag, ver32_t *version)
Sampa Misra432e1872019-02-13 03:49:43 -0600314{
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600315 if (msg == NULL || next_transfer_handle == NULL ||
vkaverapa6575b82019-04-03 05:33:52 -0500316 transfer_flag == NULL || completion_code == NULL) {
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600317 return PLDM_ERROR_INVALID_DATA;
318 }
319
George Liu684a7162019-12-06 15:10:52 +0800320 *completion_code = msg->payload[0];
321 if (PLDM_SUCCESS != *completion_code) {
322 return PLDM_SUCCESS;
323 }
324
vkaverapa6575b82019-04-03 05:33:52 -0500325 if (payload_length < PLDM_GET_VERSION_RESP_BYTES) {
326 return PLDM_ERROR_INVALID_LENGTH;
327 }
328
Priyanga4b790ce2019-06-10 01:30:09 -0500329 struct pldm_get_version_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500330 (struct pldm_get_version_resp *)msg->payload;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600331
Priyanga4b790ce2019-06-10 01:30:09 -0500332 *next_transfer_handle = le32toh(response->next_transfer_handle);
333 *transfer_flag = response->transfer_flag;
334 memcpy(version, (uint8_t *)response->version_data, sizeof(ver32_t));
Sampa Misra432e1872019-02-13 03:49:43 -0600335
336 return PLDM_SUCCESS;
337}
John Wang5c4f80d2019-07-29 11:12:18 +0800338
Sridevi Rameshbc6ff262019-12-12 04:58:35 -0600339int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg)
340{
341 if (msg == NULL) {
342 return PLDM_ERROR_INVALID_DATA;
343 }
344
345 struct pldm_header_info header = {0};
346 header.instance = instance_id;
347 header.msg_type = PLDM_REQUEST;
348 header.command = PLDM_GET_TID;
Sridevi Rameshbc6ff262019-12-12 04:58:35 -0600349
George Liub7095ff2021-06-14 16:01:57 +0800350 return pack_pldm_header(&header, &(msg->hdr));
Sridevi Rameshbc6ff262019-12-12 04:58:35 -0600351}
John Wang5c4f80d2019-07-29 11:12:18 +0800352int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code,
353 uint8_t tid, struct pldm_msg *msg)
354{
355 if (msg == NULL) {
356 return PLDM_ERROR_INVALID_DATA;
357 }
358
John Wang5c4f80d2019-07-29 11:12:18 +0800359 struct pldm_header_info header = {0};
360 header.instance = instance_id;
361 header.msg_type = PLDM_RESPONSE;
362 header.command = PLDM_GET_TID;
John Wang5c4f80d2019-07-29 11:12:18 +0800363
George Liub7095ff2021-06-14 16:01:57 +0800364 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
365 if (rc != PLDM_SUCCESS) {
366 return rc;
367 }
368
369 struct pldm_get_tid_resp *response =
370 (struct pldm_get_tid_resp *)msg->payload;
371 response->completion_code = completion_code;
John Wang5c4f80d2019-07-29 11:12:18 +0800372 response->tid = tid;
373
374 return PLDM_SUCCESS;
375}
376
377int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length,
378 uint8_t *completion_code, uint8_t *tid)
379{
380 if (msg == NULL || tid == NULL || completion_code == NULL) {
381 return PLDM_ERROR_INVALID_DATA;
382 }
383
George Liu684a7162019-12-06 15:10:52 +0800384 *completion_code = msg->payload[0];
385 if (PLDM_SUCCESS != *completion_code) {
386 return PLDM_SUCCESS;
387 }
388
John Wang5c4f80d2019-07-29 11:12:18 +0800389 if (payload_length != PLDM_GET_TID_RESP_BYTES) {
390 return PLDM_ERROR_INVALID_LENGTH;
391 }
392
393 struct pldm_get_tid_resp *response =
394 (struct pldm_get_tid_resp *)msg->payload;
John Wang5c4f80d2019-07-29 11:12:18 +0800395
396 *tid = response->tid;
397
398 return PLDM_SUCCESS;
399}
John Wang7f02d702019-12-03 13:38:14 +0800400
401int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command,
402 uint8_t cc, struct pldm_msg *msg)
403{
John Wang7f02d702019-12-03 13:38:14 +0800404 if (msg == NULL) {
405 return PLDM_ERROR_INVALID_DATA;
406 }
407
George Liub7095ff2021-06-14 16:01:57 +0800408 struct pldm_header_info header = {0};
John Wang7f02d702019-12-03 13:38:14 +0800409 header.instance = instance_id;
410 header.msg_type = PLDM_RESPONSE;
411 header.pldm_type = type;
412 header.command = command;
George Liub7095ff2021-06-14 16:01:57 +0800413
414 uint8_t rc = pack_pldm_header(&header, &msg->hdr);
John Wang7f02d702019-12-03 13:38:14 +0800415 if (rc != PLDM_SUCCESS) {
416 return rc;
417 }
418
419 msg->payload[0] = cc;
420
421 return PLDM_SUCCESS;
422}
gokulsanker138ceba2021-04-05 13:25:25 +0530423
424int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id,
425 uint8_t pldm_type, uint8_t command,
426 struct pldm_msg *msg)
427{
gokulsanker138ceba2021-04-05 13:25:25 +0530428 if (msg == NULL) {
429 return PLDM_ERROR_INVALID_DATA;
430 }
George Liub7095ff2021-06-14 16:01:57 +0800431
432 struct pldm_header_info header = {0};
gokulsanker138ceba2021-04-05 13:25:25 +0530433 header.msg_type = msg_type;
434 header.instance = instance_id;
435 header.pldm_type = pldm_type;
436 header.command = command;
George Liub7095ff2021-06-14 16:01:57 +0800437 return pack_pldm_header(&header, &(msg->hdr));
gokulsanker138ceba2021-04-05 13:25:25 +0530438}