xref: /openbmc/libpldm/src/dsp/base.c (revision d861a681)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #include "api.h"
3 #include "dsp/base.h"
4 
5 #include <assert.h>
6 #include <libpldm/base.h>
7 #include <libpldm/pldm_types.h>
8 
9 #include <endian.h>
10 #include <errno.h>
11 #include <stdint.h>
12 #include <string.h>
13 
pack_pldm_header_errno(const struct pldm_header_info * hdr,struct pldm_msg_hdr * msg)14 int pack_pldm_header_errno(const struct pldm_header_info *hdr,
15 			   struct pldm_msg_hdr *msg)
16 {
17 	if (msg == NULL || hdr == NULL) {
18 		return -EINVAL;
19 	}
20 
21 	if (hdr->msg_type != PLDM_RESPONSE && hdr->msg_type != PLDM_REQUEST &&
22 	    hdr->msg_type != PLDM_ASYNC_REQUEST_NOTIFY) {
23 		return -EINVAL;
24 	}
25 
26 	if (hdr->instance > PLDM_INSTANCE_MAX) {
27 		return -EINVAL;
28 	}
29 
30 	if (hdr->pldm_type > (PLDM_MAX_TYPES - 1)) {
31 		return -ENOMSG;
32 	}
33 
34 	uint8_t datagram = (hdr->msg_type == PLDM_ASYNC_REQUEST_NOTIFY) ? 1 : 0;
35 
36 	if (hdr->msg_type == PLDM_RESPONSE) {
37 		msg->request = PLDM_RESPONSE;
38 	} else if (hdr->msg_type == PLDM_REQUEST ||
39 		   hdr->msg_type == PLDM_ASYNC_REQUEST_NOTIFY) {
40 		msg->request = PLDM_REQUEST;
41 	}
42 	msg->datagram = datagram;
43 	msg->reserved = 0;
44 	msg->instance_id = hdr->instance;
45 	msg->header_ver = PLDM_CURRENT_VERSION;
46 	msg->type = hdr->pldm_type;
47 	msg->command = hdr->command;
48 
49 	return 0;
50 }
51 
unpack_pldm_header_errno(const struct pldm_msg_hdr * msg,struct pldm_header_info * hdr)52 int unpack_pldm_header_errno(const struct pldm_msg_hdr *msg,
53 			     struct pldm_header_info *hdr)
54 {
55 	if (msg == NULL) {
56 		return -EINVAL;
57 	}
58 
59 	if (msg->request == PLDM_RESPONSE) {
60 		hdr->msg_type = PLDM_RESPONSE;
61 	} else {
62 		hdr->msg_type = msg->datagram ? PLDM_ASYNC_REQUEST_NOTIFY :
63 						PLDM_REQUEST;
64 	}
65 
66 	hdr->instance = msg->instance_id;
67 	hdr->pldm_type = msg->type;
68 	hdr->command = msg->command;
69 
70 	return 0;
71 }
72 
73 LIBPLDM_ABI_STABLE
pack_pldm_header(const struct pldm_header_info * hdr,struct pldm_msg_hdr * msg)74 uint8_t pack_pldm_header(const struct pldm_header_info *hdr,
75 			 struct pldm_msg_hdr *msg)
76 {
77 	enum pldm_completion_codes cc;
78 	int rc;
79 
80 	rc = pack_pldm_header_errno(hdr, msg);
81 	if (!rc) {
82 		return PLDM_SUCCESS;
83 	}
84 
85 	cc = pldm_xlate_errno(rc);
86 	assert(cc < UINT8_MAX);
87 	if (cc > UINT8_MAX) {
88 		static_assert(PLDM_ERROR < UINT8_MAX, "Unable to report error");
89 		return PLDM_ERROR;
90 	}
91 
92 	return cc;
93 }
94 
95 LIBPLDM_ABI_STABLE
unpack_pldm_header(const struct pldm_msg_hdr * msg,struct pldm_header_info * hdr)96 uint8_t unpack_pldm_header(const struct pldm_msg_hdr *msg,
97 			   struct pldm_header_info *hdr)
98 {
99 	enum pldm_completion_codes cc;
100 	int rc;
101 
102 	rc = unpack_pldm_header_errno(msg, hdr);
103 	if (!rc) {
104 		return PLDM_SUCCESS;
105 	}
106 
107 	cc = pldm_xlate_errno(rc);
108 	assert(cc < UINT8_MAX);
109 	if (cc > UINT8_MAX) {
110 		static_assert(PLDM_ERROR < UINT8_MAX, "Unable to report error");
111 		return PLDM_ERROR;
112 	}
113 
114 	return cc;
115 }
116 
117 LIBPLDM_ABI_STABLE
pldm_msg_hdr_correlate_response(const struct pldm_msg_hdr * req,const struct pldm_msg_hdr * resp)118 bool pldm_msg_hdr_correlate_response(const struct pldm_msg_hdr *req,
119 				     const struct pldm_msg_hdr *resp)
120 {
121 	return req->instance_id == resp->instance_id && req->request &&
122 	       !resp->request && req->type == resp->type &&
123 	       req->command == resp->command;
124 }
125 
126 LIBPLDM_ABI_STABLE
encode_get_types_req(uint8_t instance_id,struct pldm_msg * msg)127 int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg)
128 {
129 	if (msg == NULL) {
130 		return PLDM_ERROR_INVALID_DATA;
131 	}
132 
133 	struct pldm_header_info header = { 0 };
134 	header.instance = instance_id;
135 	header.msg_type = PLDM_REQUEST;
136 	header.command = PLDM_GET_PLDM_TYPES;
137 
138 	return pack_pldm_header(&header, &(msg->hdr));
139 }
140 
141 LIBPLDM_ABI_STABLE
encode_get_commands_req(uint8_t instance_id,uint8_t type,ver32_t version,struct pldm_msg * msg)142 int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version,
143 			    struct pldm_msg *msg)
144 {
145 	if (msg == NULL) {
146 		return PLDM_ERROR_INVALID_DATA;
147 	}
148 
149 	struct pldm_header_info header = { 0 };
150 	header.instance = instance_id;
151 	header.msg_type = PLDM_REQUEST;
152 	header.command = PLDM_GET_PLDM_COMMANDS;
153 
154 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
155 	if (rc != PLDM_SUCCESS) {
156 		return rc;
157 	}
158 
159 	struct pldm_get_commands_req *request =
160 		(struct pldm_get_commands_req *)msg->payload;
161 
162 	request->type = type;
163 	request->version = version;
164 
165 	return PLDM_SUCCESS;
166 }
167 
168 LIBPLDM_ABI_STABLE
encode_get_types_resp(uint8_t instance_id,uint8_t completion_code,const bitfield8_t * types,struct pldm_msg * msg)169 int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
170 			  const bitfield8_t *types, struct pldm_msg *msg)
171 {
172 	if (msg == NULL) {
173 		return PLDM_ERROR_INVALID_DATA;
174 	}
175 
176 	struct pldm_header_info header = { 0 };
177 	header.instance = instance_id;
178 	header.msg_type = PLDM_RESPONSE;
179 	header.command = PLDM_GET_PLDM_TYPES;
180 
181 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
182 	if (rc != PLDM_SUCCESS) {
183 		return rc;
184 	}
185 
186 	struct pldm_get_types_resp *response =
187 		(struct pldm_get_types_resp *)msg->payload;
188 	response->completion_code = completion_code;
189 	if (response->completion_code == PLDM_SUCCESS) {
190 		if (types == NULL) {
191 			return PLDM_ERROR_INVALID_DATA;
192 		}
193 		memcpy(response->types, &(types->byte), PLDM_MAX_TYPES / 8);
194 	}
195 
196 	return PLDM_SUCCESS;
197 }
198 
199 LIBPLDM_ABI_STABLE
decode_get_commands_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * type,ver32_t * version)200 int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length,
201 			    uint8_t *type, ver32_t *version)
202 {
203 	if (msg == NULL || type == NULL || version == NULL) {
204 		return PLDM_ERROR_INVALID_DATA;
205 	}
206 
207 	if (payload_length != PLDM_GET_COMMANDS_REQ_BYTES) {
208 		return PLDM_ERROR_INVALID_LENGTH;
209 	}
210 
211 	struct pldm_get_commands_req *request =
212 		(struct pldm_get_commands_req *)msg->payload;
213 	*type = request->type;
214 	*version = request->version;
215 	return PLDM_SUCCESS;
216 }
217 
218 LIBPLDM_ABI_STABLE
encode_get_commands_resp(uint8_t instance_id,uint8_t completion_code,const bitfield8_t * commands,struct pldm_msg * msg)219 int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
220 			     const bitfield8_t *commands, struct pldm_msg *msg)
221 {
222 	if (msg == NULL) {
223 		return PLDM_ERROR_INVALID_DATA;
224 	}
225 
226 	struct pldm_header_info header = { 0 };
227 	header.instance = instance_id;
228 	header.msg_type = PLDM_RESPONSE;
229 	header.command = PLDM_GET_PLDM_COMMANDS;
230 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
231 	if (rc != PLDM_SUCCESS) {
232 		return rc;
233 	}
234 
235 	struct pldm_get_commands_resp *response =
236 		(struct pldm_get_commands_resp *)msg->payload;
237 	response->completion_code = completion_code;
238 	if (response->completion_code == PLDM_SUCCESS) {
239 		if (commands == NULL) {
240 			return PLDM_ERROR_INVALID_DATA;
241 		}
242 		memcpy(response->commands, &(commands->byte),
243 		       PLDM_MAX_CMDS_PER_TYPE / 8);
244 	}
245 
246 	return PLDM_SUCCESS;
247 }
248 
249 LIBPLDM_ABI_STABLE
decode_get_types_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,bitfield8_t * types)250 int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length,
251 			  uint8_t *completion_code, bitfield8_t *types)
252 {
253 	if (msg == NULL || types == NULL || completion_code == NULL) {
254 		return PLDM_ERROR_INVALID_DATA;
255 	}
256 
257 	*completion_code = msg->payload[0];
258 	if (PLDM_SUCCESS != *completion_code) {
259 		return PLDM_SUCCESS;
260 	}
261 
262 	if (payload_length != PLDM_GET_TYPES_RESP_BYTES) {
263 		return PLDM_ERROR_INVALID_LENGTH;
264 	}
265 
266 	struct pldm_get_types_resp *response =
267 		(struct pldm_get_types_resp *)msg->payload;
268 
269 	memcpy(&(types->byte), response->types, PLDM_MAX_TYPES / 8);
270 
271 	return PLDM_SUCCESS;
272 }
273 
274 LIBPLDM_ABI_STABLE
decode_get_commands_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,bitfield8_t * commands)275 int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length,
276 			     uint8_t *completion_code, bitfield8_t *commands)
277 {
278 	if (msg == NULL || commands == NULL || completion_code == NULL) {
279 		return PLDM_ERROR_INVALID_DATA;
280 	}
281 
282 	*completion_code = msg->payload[0];
283 	if (PLDM_SUCCESS != *completion_code) {
284 		return PLDM_SUCCESS;
285 	}
286 
287 	if (payload_length != PLDM_GET_COMMANDS_RESP_BYTES) {
288 		return PLDM_ERROR_INVALID_LENGTH;
289 	}
290 
291 	struct pldm_get_commands_resp *response =
292 		(struct pldm_get_commands_resp *)msg->payload;
293 
294 	memcpy(&(commands->byte), response->commands,
295 	       PLDM_MAX_CMDS_PER_TYPE / 8);
296 
297 	return PLDM_SUCCESS;
298 }
299 
300 LIBPLDM_ABI_STABLE
encode_get_version_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_opflag,uint8_t type,struct pldm_msg * msg)301 int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
302 			   uint8_t transfer_opflag, uint8_t type,
303 			   struct pldm_msg *msg)
304 {
305 	if (NULL == msg) {
306 		return PLDM_ERROR_INVALID_DATA;
307 	}
308 
309 	struct pldm_header_info header = { 0 };
310 	header.msg_type = PLDM_REQUEST;
311 	header.instance = instance_id;
312 	header.pldm_type = PLDM_BASE;
313 	header.command = PLDM_GET_PLDM_VERSION;
314 
315 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
316 	if (rc != PLDM_SUCCESS) {
317 		return rc;
318 	}
319 
320 	struct pldm_get_version_req *request =
321 		(struct pldm_get_version_req *)msg->payload;
322 	transfer_handle = htole32(transfer_handle);
323 	request->transfer_handle = transfer_handle;
324 	request->transfer_opflag = transfer_opflag;
325 	request->type = type;
326 
327 	return PLDM_SUCCESS;
328 }
329 
330 LIBPLDM_ABI_STABLE
encode_get_version_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,uint8_t transfer_flag,const ver32_t * version_data,size_t version_size,struct pldm_msg * msg)331 int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
332 			    uint32_t next_transfer_handle,
333 			    uint8_t transfer_flag, const ver32_t *version_data,
334 			    size_t version_size, struct pldm_msg *msg)
335 {
336 	if (NULL == msg) {
337 		return PLDM_ERROR_INVALID_DATA;
338 	}
339 
340 	struct pldm_header_info header = { 0 };
341 	header.msg_type = PLDM_RESPONSE;
342 	header.instance = instance_id;
343 	header.pldm_type = PLDM_BASE;
344 	header.command = PLDM_GET_PLDM_VERSION;
345 
346 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
347 	if (rc != PLDM_SUCCESS) {
348 		return rc;
349 	}
350 
351 	struct pldm_get_version_resp *response =
352 		(struct pldm_get_version_resp *)msg->payload;
353 	response->completion_code = completion_code;
354 	if (response->completion_code == PLDM_SUCCESS) {
355 		response->next_transfer_handle = htole32(next_transfer_handle);
356 		response->transfer_flag = transfer_flag;
357 		memcpy(response->version_data, (uint8_t *)version_data,
358 		       version_size);
359 	}
360 	return PLDM_SUCCESS;
361 }
362 
363 LIBPLDM_ABI_STABLE
decode_get_version_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_opflag,uint8_t * type)364 int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length,
365 			   uint32_t *transfer_handle, uint8_t *transfer_opflag,
366 			   uint8_t *type)
367 {
368 	if (payload_length != PLDM_GET_VERSION_REQ_BYTES) {
369 		return PLDM_ERROR_INVALID_LENGTH;
370 	}
371 
372 	struct pldm_get_version_req *request =
373 		(struct pldm_get_version_req *)msg->payload;
374 	*transfer_handle = le32toh(request->transfer_handle);
375 	*transfer_opflag = request->transfer_opflag;
376 	*type = request->type;
377 	return PLDM_SUCCESS;
378 }
379 
380 LIBPLDM_ABI_STABLE
decode_get_version_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle,uint8_t * transfer_flag,ver32_t * version)381 int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length,
382 			    uint8_t *completion_code,
383 			    uint32_t *next_transfer_handle,
384 			    uint8_t *transfer_flag, ver32_t *version)
385 {
386 	if (msg == NULL || next_transfer_handle == NULL ||
387 	    transfer_flag == NULL || completion_code == NULL) {
388 		return PLDM_ERROR_INVALID_DATA;
389 	}
390 
391 	*completion_code = msg->payload[0];
392 	if (PLDM_SUCCESS != *completion_code) {
393 		return PLDM_SUCCESS;
394 	}
395 
396 	if (payload_length < PLDM_GET_VERSION_RESP_BYTES) {
397 		return PLDM_ERROR_INVALID_LENGTH;
398 	}
399 
400 	struct pldm_get_version_resp *response =
401 		(struct pldm_get_version_resp *)msg->payload;
402 
403 	*next_transfer_handle = le32toh(response->next_transfer_handle);
404 	*transfer_flag = response->transfer_flag;
405 	memcpy(version, (uint8_t *)response->version_data, sizeof(ver32_t));
406 
407 	return PLDM_SUCCESS;
408 }
409 
410 LIBPLDM_ABI_STABLE
encode_get_tid_req(uint8_t instance_id,struct pldm_msg * msg)411 int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg)
412 {
413 	if (msg == NULL) {
414 		return PLDM_ERROR_INVALID_DATA;
415 	}
416 
417 	struct pldm_header_info header = { 0 };
418 	header.instance = instance_id;
419 	header.msg_type = PLDM_REQUEST;
420 	header.command = PLDM_GET_TID;
421 
422 	return pack_pldm_header(&header, &(msg->hdr));
423 }
424 
425 LIBPLDM_ABI_STABLE
encode_get_tid_resp(uint8_t instance_id,uint8_t completion_code,uint8_t tid,struct pldm_msg * msg)426 int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code,
427 			uint8_t tid, struct pldm_msg *msg)
428 {
429 	if (msg == NULL) {
430 		return PLDM_ERROR_INVALID_DATA;
431 	}
432 
433 	struct pldm_header_info header = { 0 };
434 	header.instance = instance_id;
435 	header.msg_type = PLDM_RESPONSE;
436 	header.command = PLDM_GET_TID;
437 
438 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
439 	if (rc != PLDM_SUCCESS) {
440 		return rc;
441 	}
442 
443 	struct pldm_get_tid_resp *response =
444 		(struct pldm_get_tid_resp *)msg->payload;
445 	response->completion_code = completion_code;
446 	response->tid = tid;
447 
448 	return PLDM_SUCCESS;
449 }
450 
451 LIBPLDM_ABI_STABLE
decode_get_tid_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * tid)452 int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length,
453 			uint8_t *completion_code, uint8_t *tid)
454 {
455 	if (msg == NULL || tid == NULL || completion_code == NULL) {
456 		return PLDM_ERROR_INVALID_DATA;
457 	}
458 
459 	*completion_code = msg->payload[0];
460 	if (PLDM_SUCCESS != *completion_code) {
461 		return PLDM_SUCCESS;
462 	}
463 
464 	if (payload_length != PLDM_GET_TID_RESP_BYTES) {
465 		return PLDM_ERROR_INVALID_LENGTH;
466 	}
467 
468 	struct pldm_get_tid_resp *response =
469 		(struct pldm_get_tid_resp *)msg->payload;
470 
471 	*tid = response->tid;
472 
473 	return PLDM_SUCCESS;
474 }
475 
476 LIBPLDM_ABI_STABLE
encode_set_tid_req(uint8_t instance_id,uint8_t tid,struct pldm_msg * msg)477 int encode_set_tid_req(uint8_t instance_id, uint8_t tid, struct pldm_msg *msg)
478 {
479 	if (msg == NULL) {
480 		return PLDM_ERROR_INVALID_DATA;
481 	}
482 
483 	if (tid == 0x0 || tid == 0xff) {
484 		return PLDM_ERROR_INVALID_DATA;
485 	}
486 
487 	struct pldm_header_info header = { 0 };
488 	header.instance = instance_id;
489 	header.msg_type = PLDM_REQUEST;
490 	header.command = PLDM_SET_TID;
491 
492 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
493 	if (rc != PLDM_SUCCESS) {
494 		return rc;
495 	}
496 
497 	struct pldm_set_tid_req *request =
498 		(struct pldm_set_tid_req *)msg->payload;
499 	request->tid = tid;
500 
501 	return PLDM_SUCCESS;
502 }
503 
504 LIBPLDM_ABI_STABLE
decode_multipart_receive_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * pldm_type,uint8_t * transfer_opflag,uint32_t * transfer_ctx,uint32_t * transfer_handle,uint32_t * section_offset,uint32_t * section_length)505 int decode_multipart_receive_req(const struct pldm_msg *msg,
506 				 size_t payload_length, uint8_t *pldm_type,
507 				 uint8_t *transfer_opflag,
508 				 uint32_t *transfer_ctx,
509 				 uint32_t *transfer_handle,
510 				 uint32_t *section_offset,
511 				 uint32_t *section_length)
512 {
513 	if (msg == NULL || pldm_type == NULL || transfer_opflag == NULL ||
514 	    transfer_ctx == NULL || transfer_handle == NULL ||
515 	    section_offset == NULL || section_length == NULL) {
516 		return PLDM_ERROR_INVALID_DATA;
517 	}
518 
519 	if (payload_length != PLDM_MULTIPART_RECEIVE_REQ_BYTES) {
520 		return PLDM_ERROR_INVALID_LENGTH;
521 	}
522 
523 	struct pldm_multipart_receive_req *request =
524 		(struct pldm_multipart_receive_req *)msg->payload;
525 
526 	if (request->pldm_type != PLDM_BASE) {
527 		return PLDM_ERROR_INVALID_PLDM_TYPE;
528 	}
529 
530 	// Any enum value above PLDM_XFER_CURRENT_PART is invalid.
531 	if (request->transfer_opflag > PLDM_XFER_CURRENT_PART) {
532 		return PLDM_INVALID_TRANSFER_OPERATION_FLAG;
533 	}
534 
535 	// A section offset of 0 is only valid on FIRST_PART or COMPLETE Xfers.
536 	uint32_t sec_offset = le32toh(request->section_offset);
537 	if (sec_offset == 0 &&
538 	    (request->transfer_opflag != PLDM_XFER_FIRST_PART &&
539 	     request->transfer_opflag != PLDM_XFER_COMPLETE)) {
540 		return PLDM_ERROR_INVALID_DATA;
541 	}
542 
543 	uint32_t handle = le32toh(request->transfer_handle);
544 	if (handle == 0 && request->transfer_opflag != PLDM_XFER_COMPLETE) {
545 		return PLDM_ERROR_INVALID_DATA;
546 	}
547 
548 	*pldm_type = request->pldm_type;
549 	*transfer_opflag = request->transfer_opflag;
550 	*transfer_ctx = request->transfer_ctx;
551 	*transfer_handle = handle;
552 	*section_offset = sec_offset;
553 	*section_length = le32toh(request->section_length);
554 
555 	return PLDM_SUCCESS;
556 }
557 
558 LIBPLDM_ABI_STABLE
encode_cc_only_resp(uint8_t instance_id,uint8_t type,uint8_t command,uint8_t cc,struct pldm_msg * msg)559 int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command,
560 			uint8_t cc, struct pldm_msg *msg)
561 {
562 	if (msg == NULL) {
563 		return PLDM_ERROR_INVALID_DATA;
564 	}
565 
566 	struct pldm_header_info header = { 0 };
567 	header.instance = instance_id;
568 	header.msg_type = PLDM_RESPONSE;
569 	header.pldm_type = type;
570 	header.command = command;
571 
572 	uint8_t rc = pack_pldm_header(&header, &msg->hdr);
573 	if (rc != PLDM_SUCCESS) {
574 		return rc;
575 	}
576 
577 	msg->payload[0] = cc;
578 
579 	return PLDM_SUCCESS;
580 }
581 
582 LIBPLDM_ABI_STABLE
encode_pldm_header_only(uint8_t msg_type,uint8_t instance_id,uint8_t pldm_type,uint8_t command,struct pldm_msg * msg)583 int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id,
584 			    uint8_t pldm_type, uint8_t command,
585 			    struct pldm_msg *msg)
586 {
587 	if (msg == NULL) {
588 		return PLDM_ERROR_INVALID_DATA;
589 	}
590 
591 	struct pldm_header_info header = { 0 };
592 	header.msg_type = msg_type;
593 	header.instance = instance_id;
594 	header.pldm_type = pldm_type;
595 	header.command = command;
596 	return pack_pldm_header(&header, &(msg->hdr));
597 }
598