blob: b34045c3efb4d8ed93d358579bc0ada3ee017e9a [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;
37 msg->header_ver = 0;
38 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
vkaverapa6575b82019-04-03 05:33:52 -0500182 if (payload_length != PLDM_GET_TYPES_RESP_BYTES) {
183 return PLDM_ERROR_INVALID_LENGTH;
184 }
185
Priyanga4b790ce2019-06-10 01:30:09 -0500186 struct pldm_get_types_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500187 (struct pldm_get_types_resp *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500188 *completion_code = response->completion_code;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600189 if (PLDM_SUCCESS != *completion_code) {
190 return PLDM_SUCCESS;
191 };
192
Priyanga4b790ce2019-06-10 01:30:09 -0500193 memcpy(&(types->byte), response->types, PLDM_MAX_TYPES / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600194
195 return PLDM_SUCCESS;
196}
197
Zahed Hossain223a73d2019-07-04 12:46:18 -0500198int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600199 uint8_t *completion_code, bitfield8_t *commands)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600200{
vkaverapa6575b82019-04-03 05:33:52 -0500201 if (msg == NULL || commands == NULL || completion_code == NULL) {
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600202 return PLDM_ERROR_INVALID_DATA;
203 }
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600204
vkaverapa6575b82019-04-03 05:33:52 -0500205 if (payload_length != PLDM_GET_COMMANDS_RESP_BYTES) {
206 return PLDM_ERROR_INVALID_LENGTH;
207 }
208
Priyanga4b790ce2019-06-10 01:30:09 -0500209 struct pldm_get_commands_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500210 (struct pldm_get_commands_resp *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500211 *completion_code = response->completion_code;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600212 if (PLDM_SUCCESS != *completion_code) {
213 return PLDM_SUCCESS;
214 };
215
Priyanga4b790ce2019-06-10 01:30:09 -0500216 memcpy(&(commands->byte), response->commands,
vkaverapa6575b82019-04-03 05:33:52 -0500217 PLDM_MAX_CMDS_PER_TYPE / 8);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600218
219 return PLDM_SUCCESS;
220}
Sampa Misra432e1872019-02-13 03:49:43 -0600221
222int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
223 uint8_t transfer_opflag, uint8_t type,
224 struct pldm_msg *msg)
225{
226 struct pldm_header_info header = {0};
227 int rc = PLDM_SUCCESS;
228
229 if (NULL == msg) {
230 return PLDM_ERROR_INVALID_DATA;
231 }
232
233 header.msg_type = PLDM_REQUEST;
234 header.instance = instance_id;
235 header.pldm_type = PLDM_BASE;
236 header.command = PLDM_GET_PLDM_VERSION;
237
238 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
239 return rc;
240 }
241
Priyanga4b790ce2019-06-10 01:30:09 -0500242 struct pldm_get_version_req *request =
243 (struct pldm_get_version_req *)msg->payload;
Sampa Misra432e1872019-02-13 03:49:43 -0600244 transfer_handle = htole32(transfer_handle);
Priyanga4b790ce2019-06-10 01:30:09 -0500245 request->transfer_handle = transfer_handle;
246 request->transfer_opflag = transfer_opflag;
247 request->type = type;
Sampa Misra432e1872019-02-13 03:49:43 -0600248
249 return PLDM_SUCCESS;
250}
251
252int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
253 uint32_t next_transfer_handle,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600254 uint8_t transfer_flag, const ver32_t *version_data,
Sampa Misra432e1872019-02-13 03:49:43 -0600255 size_t version_size, struct pldm_msg *msg)
256{
257 struct pldm_header_info header = {0};
258 int rc = PLDM_SUCCESS;
Priyanga4b790ce2019-06-10 01:30:09 -0500259 struct pldm_get_version_resp *response =
260 (struct pldm_get_version_resp *)msg->payload;
261 response->completion_code = completion_code;
262 if (response->completion_code == PLDM_SUCCESS) {
Sampa Misra432e1872019-02-13 03:49:43 -0600263
264 header.msg_type = PLDM_RESPONSE;
265 header.instance = instance_id;
266 header.pldm_type = PLDM_BASE;
267 header.command = PLDM_GET_PLDM_VERSION;
268
269 if ((rc = pack_pldm_header(&header, &(msg->hdr))) >
270 PLDM_SUCCESS) {
271 return rc;
272 }
Priyanga4b790ce2019-06-10 01:30:09 -0500273 response->next_transfer_handle = htole32(next_transfer_handle);
274 response->transfer_flag = transfer_flag;
275 memcpy(response->version_data, (uint8_t *)version_data,
276 version_size);
Sampa Misra432e1872019-02-13 03:49:43 -0600277 }
278 return PLDM_SUCCESS;
279}
280
Zahed Hossain223a73d2019-07-04 12:46:18 -0500281int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length,
Sampa Misra432e1872019-02-13 03:49:43 -0600282 uint32_t *transfer_handle, uint8_t *transfer_opflag,
283 uint8_t *type)
284{
vkaverapa6575b82019-04-03 05:33:52 -0500285
286 if (payload_length != PLDM_GET_VERSION_REQ_BYTES) {
287 return PLDM_ERROR_INVALID_LENGTH;
288 }
289
Priyanga4b790ce2019-06-10 01:30:09 -0500290 struct pldm_get_version_req *request =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500291 (struct pldm_get_version_req *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500292 *transfer_handle = le32toh(request->transfer_handle);
293 *transfer_opflag = request->transfer_opflag;
294 *type = request->type;
Sampa Misra432e1872019-02-13 03:49:43 -0600295 return PLDM_SUCCESS;
296}
297
Zahed Hossain223a73d2019-07-04 12:46:18 -0500298int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length,
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600299 uint8_t *completion_code,
Sampa Misra432e1872019-02-13 03:49:43 -0600300 uint32_t *next_transfer_handle,
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600301 uint8_t *transfer_flag, ver32_t *version)
Sampa Misra432e1872019-02-13 03:49:43 -0600302{
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600303 if (msg == NULL || next_transfer_handle == NULL ||
vkaverapa6575b82019-04-03 05:33:52 -0500304 transfer_flag == NULL || completion_code == NULL) {
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600305 return PLDM_ERROR_INVALID_DATA;
306 }
307
vkaverapa6575b82019-04-03 05:33:52 -0500308 if (payload_length < PLDM_GET_VERSION_RESP_BYTES) {
309 return PLDM_ERROR_INVALID_LENGTH;
310 }
311
Priyanga4b790ce2019-06-10 01:30:09 -0500312 struct pldm_get_version_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500313 (struct pldm_get_version_resp *)msg->payload;
Priyanga4b790ce2019-06-10 01:30:09 -0500314 *completion_code = response->completion_code;
Deepak Kodihalli8c643462019-02-21 10:43:36 -0600315 if (PLDM_SUCCESS != *completion_code) {
316 return PLDM_SUCCESS;
317 };
318
Priyanga4b790ce2019-06-10 01:30:09 -0500319 *next_transfer_handle = le32toh(response->next_transfer_handle);
320 *transfer_flag = response->transfer_flag;
321 memcpy(version, (uint8_t *)response->version_data, sizeof(ver32_t));
Sampa Misra432e1872019-02-13 03:49:43 -0600322
323 return PLDM_SUCCESS;
324}
John Wang5c4f80d2019-07-29 11:12:18 +0800325
326int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code,
327 uint8_t tid, struct pldm_msg *msg)
328{
329 if (msg == NULL) {
330 return PLDM_ERROR_INVALID_DATA;
331 }
332
333 struct pldm_get_tid_resp *response =
334 (struct pldm_get_tid_resp *)msg->payload;
335
336 response->completion_code = completion_code;
337 struct pldm_header_info header = {0};
338 header.instance = instance_id;
339 header.msg_type = PLDM_RESPONSE;
340 header.command = PLDM_GET_TID;
341 pack_pldm_header(&header, &(msg->hdr));
342
343 response->tid = tid;
344
345 return PLDM_SUCCESS;
346}
347
348int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length,
349 uint8_t *completion_code, uint8_t *tid)
350{
351 if (msg == NULL || tid == NULL || completion_code == NULL) {
352 return PLDM_ERROR_INVALID_DATA;
353 }
354
355 if (payload_length != PLDM_GET_TID_RESP_BYTES) {
356 return PLDM_ERROR_INVALID_LENGTH;
357 }
358
359 struct pldm_get_tid_resp *response =
360 (struct pldm_get_tid_resp *)msg->payload;
361 *completion_code = response->completion_code;
362 if (PLDM_SUCCESS != *completion_code) {
363 return PLDM_SUCCESS;
364 };
365
366 *tid = response->tid;
367
368 return PLDM_SUCCESS;
369}
John Wang7f02d702019-12-03 13:38:14 +0800370
371int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command,
372 uint8_t cc, struct pldm_msg *msg)
373{
374 struct pldm_header_info header = {0};
375
376 if (msg == NULL) {
377 return PLDM_ERROR_INVALID_DATA;
378 }
379
380 header.instance = instance_id;
381 header.msg_type = PLDM_RESPONSE;
382 header.pldm_type = type;
383 header.command = command;
384 int rc = pack_pldm_header(&header, &msg->hdr);
385 if (rc != PLDM_SUCCESS) {
386 return rc;
387 }
388
389 msg->payload[0] = cc;
390
391 return PLDM_SUCCESS;
392}