1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2 #ifndef BASE_H 3 #define BASE_H 4 5 #ifdef __cplusplus 6 extern "C" { 7 #endif 8 9 #include <libpldm/compiler.h> 10 #include <libpldm/pldm_types.h> 11 #include <libpldm/utils.h> 12 13 #include <asm/byteorder.h> 14 #include <stdalign.h> 15 #include <stdbool.h> 16 #include <stddef.h> 17 #include <stdint.h> 18 19 typedef uint8_t pldm_tid_t; 20 21 /** @brief PLDM Types 22 */ 23 enum pldm_supported_types { 24 PLDM_BASE = 0x00, 25 PLDM_SMBIOS = 0x01, 26 PLDM_PLATFORM = 0x02, 27 PLDM_BIOS = 0x03, 28 PLDM_FRU = 0x04, 29 PLDM_FWUP = 0x05, 30 PLDM_RDE = 0x06, 31 PLDM_FILE = 0x07, 32 PLDM_OEM = 0x3f, 33 }; 34 35 /** @brief PLDM Commands 36 */ 37 enum pldm_supported_commands { 38 PLDM_SET_TID = 0x1, 39 PLDM_GET_TID = 0x2, 40 PLDM_GET_PLDM_VERSION = 0x3, 41 PLDM_GET_PLDM_TYPES = 0x4, 42 PLDM_GET_PLDM_COMMANDS = 0x5, 43 PLDM_SELECT_PLDM_VERSION = 0x6, 44 PLDM_NEGOTIATE_TRANSFER_PARAMETERS = 0x7, 45 PLDM_MULTIPART_SEND = 0x8, 46 PLDM_MULTIPART_RECEIVE = 0x9, 47 PLDM_GET_MULTIPART_TRANSFER_SUPPORT = 0xa, 48 }; 49 50 /** @brief PLDM base codes 51 */ 52 enum pldm_completion_codes { 53 PLDM_SUCCESS = 0x00, 54 PLDM_ERROR = 0x01, 55 PLDM_ERROR_INVALID_DATA = 0x02, 56 PLDM_ERROR_INVALID_LENGTH = 0x03, 57 PLDM_ERROR_NOT_READY = 0x04, 58 PLDM_ERROR_UNSUPPORTED_PLDM_CMD = 0x05, 59 PLDM_ERROR_INVALID_PLDM_TYPE = 0x20, 60 PLDM_INVALID_TRANSFER_OPERATION_FLAG = 0x21, 61 PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION = 0x23, 62 }; 63 64 enum transfer_op_flag { 65 PLDM_GET_NEXTPART = 0, 66 PLDM_GET_FIRSTPART = 1, 67 PLDM_ACKNOWLEDGEMENT_ONLY = 2, 68 }; 69 70 enum transfer_multipart_op_flag { 71 PLDM_XFER_FIRST_PART = 0, 72 PLDM_XFER_NEXT_PART = 1, 73 PLDM_XFER_ABORT = 2, 74 PLDM_XFER_COMPLETE = 3, 75 PLDM_XFER_CURRENT_PART = 4, 76 }; 77 78 enum pldm_base_multipart_receive_transfer_flag { 79 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START = 0x01, 80 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_MIDDLE = 0x02, 81 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END = 0x04, 82 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START_AND_END = 0x05, 83 PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_ACK_COMPLETION = 0x08, 84 }; 85 86 enum transfer_resp_flag { 87 PLDM_START = 0x01, 88 PLDM_MIDDLE = 0x02, 89 PLDM_END = 0x04, 90 PLDM_START_AND_END = 0x05, 91 }; 92 93 /** @brief PLDM transport protocol type 94 */ 95 enum pldm_transport_protocol_type { 96 PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP = 0x00, 97 PLDM_TRANSPORT_PROTOCOL_TYPE_OEM = 0xff, 98 }; 99 100 /** @enum MessageType 101 * 102 * The different message types supported by the PLDM specification. 103 */ 104 typedef enum { 105 PLDM_RESPONSE, //!< PLDM response 106 PLDM_REQUEST, //!< PLDM request 107 PLDM_RESERVED, //!< Reserved 108 PLDM_ASYNC_REQUEST_NOTIFY, //!< Unacknowledged PLDM request messages 109 } MessageType; 110 111 #define PLDM_INSTANCE_MAX 31 112 #define PLDM_MAX_TYPES 64 113 #define PLDM_MAX_CMDS_PER_TYPE 256 114 #define PLDM_MAX_TIDS 256 115 #define PLDM_TID_UNASSIGNED 0x00 116 #define PLDM_TID_RESERVED 0xff 117 118 /* Message payload lengths */ 119 #define PLDM_GET_COMMANDS_REQ_BYTES 5 120 #define PLDM_GET_VERSION_REQ_BYTES 6 121 122 /* Response lengths are inclusive of completion code */ 123 #define PLDM_GET_TYPES_REQ_BYTES 0 124 #define PLDM_GET_TYPES_RESP_BYTES 9 125 #define PLDM_GET_TID_REQ_BYTES 0 126 #define PLDM_GET_TID_RESP_BYTES 2 127 #define PLDM_SET_TID_REQ_BYTES 1 128 #define PLDM_SET_TID_RESP_BYTES 1 129 #define PLDM_GET_COMMANDS_RESP_BYTES 33 130 /* Response data has only one version and does not contain the checksum */ 131 #define PLDM_GET_VERSION_RESP_BYTES 10 132 #define PLDM_MULTIPART_RECEIVE_REQ_BYTES 18 133 #define PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES 10 134 135 #define PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES 10 136 #define PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES 11 137 138 #define PLDM_VERSION_0 0 139 #define PLDM_CURRENT_VERSION PLDM_VERSION_0 140 141 #define PLDM_TIMESTAMP104_SIZE 13 142 143 /** @brief Minimum length of response for a optional PLDM command 144 * 145 * For a optional PLDM command, the command handler might not be 146 * implemented in a device's firmware, a response contains only CC 147 * might come in, such as ERROR_UNSUPPORTED_PLDM_CMD. 148 * 149 * The description can be found in DSP0240: 150 * > For an unsupported PLDM command, the ERROR_UNSUPPORTED_PLDM_CMD 151 * > completion code shall be returned unless the responder is in a 152 * > transient state (not ready), in which it cannot process the PLDM 153 * > command. If the responder is in a transient state, it may return 154 * > the ERROR_NOT_READY completion code. 155 */ 156 #define PLDM_OPTIONAL_COMMAND_RESP_MIN_LEN 1 157 158 /** @struct pldm_msg_hdr 159 * 160 * Structure representing PLDM message header fields 161 */ 162 struct pldm_msg_hdr { 163 #if defined(__LITTLE_ENDIAN_BITFIELD) 164 uint8_t instance_id : 5; //!< Instance ID 165 uint8_t reserved : 1; //!< Reserved 166 uint8_t datagram : 1; //!< Datagram bit 167 uint8_t request : 1; //!< Request bit 168 #elif defined(__BIG_ENDIAN_BITFIELD) 169 uint8_t request : 1; //!< Request bit 170 uint8_t datagram : 1; //!< Datagram bit 171 uint8_t reserved : 1; //!< Reserved 172 uint8_t instance_id : 5; //!< Instance ID 173 #endif 174 175 #if defined(__LITTLE_ENDIAN_BITFIELD) 176 uint8_t type : 6; //!< PLDM type 177 uint8_t header_ver : 2; //!< Header version 178 #elif defined(__BIG_ENDIAN_BITFIELD) 179 uint8_t header_ver : 2; //!< Header version 180 uint8_t type : 6; //!< PLDM type 181 #endif 182 uint8_t command; //!< PLDM command code 183 } __attribute__((packed)); 184 185 // Macros for byte-swapping variables in-place 186 #define HTOLE32(X) ((X) = htole32(X)) 187 #define HTOLE16(X) ((X) = htole16(X)) 188 #define LE32TOH(X) ((X) = le32toh(X)) 189 #define LE16TOH(X) ((X) = le16toh(X)) 190 191 /** @struct pldm_msg 192 * 193 * Structure representing PLDM message 194 */ 195 struct pldm_msg { 196 struct pldm_msg_hdr hdr; //!< PLDM message header 197 uint8_t payload[1]; //!< &payload[0] is the beginning of the payload 198 } __attribute__((packed)); 199 200 /** @brief Determine the underlying object size for a @struct pldm_msg 201 * 202 * @pre @p size must be a constant expression 203 * 204 * @note Providing an expression for @p size that is not an integer constant 205 * expression will force a compilation failure. 206 * 207 * @param size The desired size of the @struct pldm_msg payload 208 */ 209 #define PLDM_MSG_SIZE(size) \ 210 (sizeof(char[(__builtin_constant_p(size)) ? 1 : -1])) * \ 211 (sizeof(struct pldm_msg) - \ 212 sizeof(((struct pldm_msg *)NULL)->payload) + (size)) 213 214 /** @brief Stack-allocate a buffer to hold a @struct pldm_msg 215 * 216 * Allocate an appropriately aligned array named @p name of type unsigned char 217 * with the necessary length to hold a payload of the requested size. 218 * 219 * @param name - The variable name used to define the buffer 220 * @param size - The desired payload length for the intended @struct pldm_msg 221 */ 222 #define PLDM_MSG_BUFFER(name, size) \ 223 alignas(struct pldm_msg) unsigned char(name)[PLDM_MSG_SIZE(size)] 224 225 /** @brief Create a pointer to a stack-allocated @struct pldm_msg 226 * 227 * Define a pointer named @p name of type @struct pldm_msg to an object on the 228 * stack of appropriate alignment and length to hold a @struct pldm_msg with a 229 * payload of @p size. 230 * 231 * @param name - The variable name for pointer 232 * @param size - The desired payload length for the underlying @struct pldm_msg 233 * buffer 234 */ 235 #ifdef __cplusplus 236 #define PLDM_MSG_DEFINE_P(name, size) \ 237 PLDM_MSG_BUFFER(name##_buf, size); \ 238 auto *(name) = new (name##_buf) pldm_msg 239 #endif 240 241 /** 242 * @brief Compare the headers from two PLDM messages to determine if the latter 243 * is a message representing a response to the former, where the former must be 244 * a request. 245 * 246 * @param[in] req - A pointer to a PLDM header object, which must represent a 247 * request 248 * @param[in] resp - A pointer to a PLDM header object, which may represent a 249 * response to the provided request. 250 * 251 * @return true if the header pointed to by resp represents a message that is a 252 * response to the header pointed to by req, otherwise false. 253 */ 254 bool pldm_msg_hdr_correlate_response(const struct pldm_msg_hdr *req, 255 const struct pldm_msg_hdr *resp); 256 257 /** @struct pldm_header_info 258 * 259 * The information needed to prepare PLDM header and this is passed to the 260 * pack_pldm_header and unpack_pldm_header API. 261 */ 262 struct pldm_header_info { 263 MessageType msg_type; //!< PLDM message type 264 uint8_t instance; //!< PLDM instance id 265 uint8_t pldm_type; //!< PLDM type 266 uint8_t command; //!< PLDM command code 267 uint8_t completion_code; //!< PLDM completion code, applies for response 268 }; 269 270 /** @struct pldm_get_types_resp 271 * 272 * Structure representing PLDM get types response. 273 */ 274 struct pldm_get_types_resp { 275 uint8_t completion_code; //!< completion code 276 bitfield8_t types[8]; //!< each bit represents whether a given PLDM Type 277 //!< is supported 278 } __attribute__((packed)); 279 280 /** @struct pldm_get_commands_req 281 * 282 * Structure representing PLDM get commands request. 283 */ 284 struct pldm_get_commands_req { 285 uint8_t type; //!< PLDM Type for which command support information is 286 //!< being requested 287 ver32_t version; //!< version for the specified PLDM Type 288 } __attribute__((packed)); 289 290 /** @struct pldm_get_commands_resp 291 * 292 * Structure representing PLDM get commands response. 293 */ 294 struct pldm_get_commands_resp { 295 uint8_t completion_code; //!< completion code 296 bitfield8_t commands[32]; //!< each bit represents whether a given PLDM 297 //!< command is supported 298 } __attribute__((packed)); 299 300 /** @struct pldm_get_version_req 301 * 302 * Structure representing PLDM get version request. 303 */ 304 struct pldm_get_version_req { 305 uint32_t transfer_handle; //!< handle to identify PLDM version data transfer 306 uint8_t transfer_opflag; //!< PLDM GetVersion operation flag 307 uint8_t type; //!< PLDM Type for which version information is being requested 308 } __attribute__((packed)); 309 310 /** @struct pldm_get_version_resp 311 * 312 * Structure representing PLDM get version response. 313 */ 314 315 struct pldm_get_version_resp { 316 uint8_t completion_code; //!< completion code 317 uint32_t next_transfer_handle; //!< next portion of PLDM version data 318 //!< transfer 319 uint8_t transfer_flag; //!< PLDM GetVersion transfer flag 320 uint8_t version_data[1]; //!< PLDM GetVersion version field 321 } __attribute__((packed)); 322 323 /** @struct pldm_set_tid_req 324 * 325 * Structure representing PLDM set tid request. 326 */ 327 328 struct pldm_set_tid_req { 329 uint8_t tid; //!< PLDM SetTID TID field 330 } __attribute__((packed)); 331 332 /** @struct pldm_get_tid_resp 333 * 334 * Structure representing PLDM get tid response. 335 */ 336 337 struct pldm_get_tid_resp { 338 uint8_t completion_code; //!< completion code 339 uint8_t tid; //!< PLDM GetTID TID field 340 } __attribute__((packed)); 341 342 /** @struct pldm_multipart_receive_req 343 * 344 * Structure representing PLDM multipart receive request. 345 */ 346 struct pldm_multipart_receive_req { 347 uint8_t pldm_type; //!< PLDM Type for the MultipartReceive 348 //!< command. 349 uint8_t transfer_opflag; //!< PLDM MultipartReceive operation flag. 350 uint32_t transfer_ctx; //!< Protocol-specifc context for this 351 //!< transfer. 352 uint32_t transfer_handle; //!< handle to identify the part of data to be 353 //!< received. 354 uint32_t section_offset; //!< The start offset for the requested 355 //!< section. 356 uint32_t section_length; //!< The length (in bytes) of the section 357 //!< requested. 358 } __attribute__((packed)); 359 360 /** @struct pldm_multipart_receive_resp 361 * 362 * Structure representing PLDM multipart receive request. 363 */ 364 struct pldm_multipart_receive_resp { 365 uint8_t completion_code; //!< Completion code of the command. 366 uint8_t transfer_flag; //!< PLDM MultipartReceive transfer flag. 367 uint32_t next_transfer_handle; //!< The handle for the next part of 368 //!< data for this section transfer. 369 struct variable_field data; 370 }; 371 372 /** @struct pldm_base_negotiate_transfer_params_req 373 * 374 * Structure representing PLDM Negotiate Transfer Parameters request 375 */ 376 struct pldm_base_negotiate_transfer_params_req { 377 uint16_t requester_part_size; 378 bitfield8_t requester_protocol_support[8]; 379 }; 380 381 /** @struct pldm_base_negotiate_transfer_params_resp 382 * 383 * Structure representing PLDM Negotiate Transfer Parameters response 384 */ 385 struct pldm_base_negotiate_transfer_params_resp { 386 uint8_t completion_code; 387 uint16_t responder_part_size; 388 bitfield8_t responder_protocol_support[8]; 389 }; 390 391 /** 392 * @brief Populate the PLDM message with the PLDM header.The caller of this API 393 * allocates buffer for the PLDM header when forming the PLDM message. 394 * The buffer is passed to this API to pack the PLDM header. 395 * 396 * @param[in] hdr - Pointer to the PLDM header information 397 * @param[out] msg - Pointer to PLDM message header 398 * 399 * @return 0 on success, otherwise PLDM error codes. 400 * @note Caller is responsible for alloc and dealloc of msg 401 * and hdr params 402 */ 403 uint8_t pack_pldm_header(const struct pldm_header_info *hdr, 404 struct pldm_msg_hdr *msg); 405 406 /** 407 * @brief Unpack the PLDM header from the PLDM message. 408 * 409 * @param[in] msg - Pointer to the PLDM message header 410 * @param[out] hdr - Pointer to the PLDM header information 411 * 412 * @return 0 on success, otherwise PLDM error codes. 413 * @note Caller is responsible for alloc and dealloc of msg 414 * and hdr params 415 */ 416 uint8_t unpack_pldm_header(const struct pldm_msg_hdr *msg, 417 struct pldm_header_info *hdr); 418 419 /* Requester */ 420 421 /* GetPLDMTypes */ 422 423 /** @brief Create a PLDM request message for GetPLDMTypes 424 * 425 * @param[in] instance_id - Message's instance id 426 * @param[in,out] msg - Message will be written to this 427 * @return pldm_completion_codes 428 * @note Caller is responsible for memory alloc and dealloc of param 429 * 'msg.payload' 430 */ 431 int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg); 432 433 /** @brief Decode a GetPLDMTypes response message 434 * 435 * Note: 436 * * If the return value is not PLDM_SUCCESS, it represents a 437 * transport layer error. 438 * * If the completion_code value is not PLDM_SUCCESS, it represents a 439 * protocol layer error and all the out-parameters are invalid. 440 * 441 * @param[in] msg - Response message 442 * @param[in] payload_length - Length of response message payload 443 * @param[out] completion_code - Pointer to response msg's PLDM completion code 444 * @param[out] types - pointer to array bitfield8_t[8] containing supported 445 * types (MAX_TYPES/8) = 8), as per DSP0240 446 * @return pldm_completion_codes 447 */ 448 int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length, 449 uint8_t *completion_code, bitfield8_t *types); 450 451 /* GetPLDMCommands */ 452 453 /** @brief Create a PLDM request message for GetPLDMCommands 454 * 455 * @param[in] instance_id - Message's instance id 456 * @param[in] type - PLDM Type 457 * @param[in] version - Version for PLDM Type 458 * @param[in,out] msg - Message will be written to this 459 * @return pldm_completion_codes 460 * @note Caller is responsible for memory alloc and dealloc of param 461 * 'msg.payload' 462 */ 463 int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version, 464 struct pldm_msg *msg); 465 466 /** @brief Decode a GetPLDMCommands response message 467 * 468 * Note: 469 * * If the return value is not PLDM_SUCCESS, it represents a 470 * transport layer error. 471 * * If the completion_code value is not PLDM_SUCCESS, it represents a 472 * protocol layer error and all the out-parameters are invalid. 473 * 474 * @param[in] msg - Response message 475 * @param[in] payload_length - Length of response message payload 476 * @param[out] completion_code - Pointer to response msg's PLDM completion code 477 * @param[in] commands - pointer to array bitfield8_t[32] containing supported 478 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240 479 * @return pldm_completion_codes 480 */ 481 int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length, 482 uint8_t *completion_code, bitfield8_t *commands); 483 484 /* GetPLDMVersion */ 485 486 /** @brief Create a PLDM request for GetPLDMVersion 487 * 488 * @param[in] instance_id - Message's instance id 489 * @param[in] transfer_handle - Handle to identify PLDM version data transfer. 490 * This handle is ignored by the responder when the 491 * transferop_flag is set to getFirstPart. 492 * @param[in] transfer_opflag - flag to indicate whether it is start of 493 * transfer 494 * @param[in] type - PLDM Type for which version is requested 495 * @param[in,out] msg - Message will be written to this 496 * @return pldm_completion_codes 497 * @note Caller is responsible for memory alloc and dealloc of param 498 * 'msg.payload' 499 */ 500 int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle, 501 uint8_t transfer_opflag, uint8_t type, 502 struct pldm_msg *msg); 503 504 /** @brief Decode a GetPLDMVersion response message 505 * 506 * Note: 507 * * If the return value is not PLDM_SUCCESS, it represents a 508 * transport layer error. 509 * * If the completion_code value is not PLDM_SUCCESS, it represents a 510 * protocol layer error and all the out-parameters are invalid. 511 * 512 * @param[in] msg - Response message 513 * @param[in] payload_length - Length of response message payload 514 * @param[out] completion_code - Pointer to response msg's PLDM completion code 515 * @param[out] next_transfer_handle - the next handle for the next part of data 516 * @param[out] transfer_flag - flag to indicate the part of data 517 * @return pldm_completion_codes 518 */ 519 int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length, 520 uint8_t *completion_code, 521 uint32_t *next_transfer_handle, 522 uint8_t *transfer_flag, ver32_t *version); 523 524 /* GetTID */ 525 526 /** @brief Decode a GetTID response message 527 * 528 * Note: 529 * * If the return value is not PLDM_SUCCESS, it represents a 530 * transport layer error. 531 * * If the completion_code value is not PLDM_SUCCESS, it represents a 532 * protocol layer error and all the out-parameters are invalid. 533 * 534 * @param[in] msg - Response message 535 * @param[in] payload_length - Length of response message payload 536 * @param[out] completion_code - Pointer to response msg's PLDM completion code 537 * @param[out] tid - Pointer to the terminus id 538 * @return pldm_completion_codes 539 */ 540 int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length, 541 uint8_t *completion_code, uint8_t *tid); 542 543 /* Responder */ 544 545 /* GetPLDMTypes */ 546 547 /** @brief Create a PLDM response message for GetPLDMTypes 548 * 549 * @param[in] instance_id - Message's instance id 550 * @param[in] completion_code - PLDM completion code 551 * @param[in] types - pointer to array bitfield8_t[8] containing supported 552 * types (MAX_TYPES/8) = 8), as per DSP0240 553 * @param[in,out] msg - Message will be written to this 554 * @return pldm_completion_codes 555 * @note Caller is responsible for memory alloc and dealloc of param 556 * 'msg.payload' 557 */ 558 int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code, 559 const bitfield8_t *types, struct pldm_msg *msg); 560 561 /* GetPLDMCommands */ 562 563 /** @brief Decode GetPLDMCommands' request data 564 * 565 * @param[in] msg - Request message 566 * @param[in] payload_length - Length of request message payload 567 * @param[out] type - PLDM Type 568 * @param[out] version - Version for PLDM Type 569 * @return pldm_completion_codes 570 */ 571 int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length, 572 uint8_t *type, ver32_t *version); 573 574 /** @brief Create a PLDM response message for GetPLDMCommands 575 * 576 * @param[in] instance_id - Message's instance id 577 * @param[in] completion_code - PLDM completion code 578 * @param[in] commands - pointer to array bitfield8_t[32] containing supported 579 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240 580 * @param[in,out] msg - Message will be written to this 581 * @return pldm_completion_codes 582 * @note Caller is responsible for memory alloc and dealloc of param 583 * 'msg.payload' 584 */ 585 int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code, 586 const bitfield8_t *commands, struct pldm_msg *msg); 587 588 /* GetPLDMVersion */ 589 590 /** @brief Create a PLDM response for GetPLDMVersion 591 * 592 * @param[in] instance_id - Message's instance id 593 * @param[in] completion_code - PLDM completion code 594 * @param[in] next_transfer_handle - Handle to identify next portion of 595 * data transfer 596 * @param[in] transfer_flag - Represents the part of transfer 597 * @param[in] version_data - the version data 598 * @param[in] version_size - size of version data 599 * @param[in,out] msg - Message will be written to this 600 * @return pldm_completion_codes 601 * @note Caller is responsible for memory alloc and dealloc of param 602 * 'msg.payload' 603 */ 604 int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code, 605 uint32_t next_transfer_handle, 606 uint8_t transfer_flag, const ver32_t *version_data, 607 size_t version_size, struct pldm_msg *msg); 608 609 /** @brief Decode a GetPLDMVersion request message 610 * 611 * @param[in] msg - Request message 612 * @param[in] payload_length - length of request message payload 613 * @param[out] transfer_handle - the handle of data 614 * @param[out] transfer_opflag - Transfer Flag 615 * @param[out] type - PLDM type for which version is requested 616 * @return pldm_completion_codes 617 */ 618 int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length, 619 uint32_t *transfer_handle, uint8_t *transfer_opflag, 620 uint8_t *type); 621 622 /* Requester */ 623 624 /* GetTID */ 625 626 /** @brief Create a PLDM request message for GetTID 627 * 628 * @param[in] instance_id - Message's instance id 629 * @param[in,out] msg - Message will be written to this 630 * @return pldm_completion_codes 631 * @note Caller is responsible for memory alloc and dealloc of param 632 * 'msg.payload' 633 */ 634 int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg); 635 636 /** @brief Create a PLDM response message for GetTID 637 * 638 * @param[in] instance_id - Message's instance id 639 * @param[in] completion_code - PLDM completion code 640 * @param[in] tid - Terminus ID 641 * @param[in,out] msg - Message will be written to this 642 * @return pldm_completion_codes 643 * @note Caller is responsible for memory alloc and dealloc of param 644 * 'msg.payload' 645 */ 646 int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code, 647 uint8_t tid, struct pldm_msg *msg); 648 649 /** @brief Create a PLDM request message for SetTID 650 * 651 * @param[in] instance_id - Message's instance id 652 * @param[in] tid - Terminus ID 653 * @param[in,out] msg - Message will be written to this 654 * @return pldm_completion_codes 655 * @note Caller is responsible for memory alloc and dealloc of param 656 * 'msg.payload' 657 */ 658 int encode_set_tid_req(uint8_t instance_id, uint8_t tid, struct pldm_msg *msg); 659 660 /** @brief Decode a SetTID request message 661 * 662 * @param[in] msg - Request message 663 * @param[in] payload_length - length of request message payload 664 * @param[out] tid - Terminus ID 665 * @return 0 on success 666 * -EINVAL if the input parameters' memory are not allocated, 667 * or tid is invalid 668 * -EOVERFLOW if the input message length is invalid 669 */ 670 int decode_set_tid_req(const struct pldm_msg *msg, size_t payload_length, 671 uint8_t *tid); 672 673 /* Responder */ 674 675 /* MultipartRecieve */ 676 677 /** @brief Decode a PLDM MultipartReceive request message 678 * 679 * @param[in] msg - Request message 680 * @param[in] payload_length - length of request message payload 681 * @param[out] pldm_type - PLDM type for which version is requested 682 * @param[out] transfer_opflag - Transfer Flag 683 * @param[out] transfer_ctx - The context of the packet 684 * @param[out] transfer_handle - The handle of data 685 * @param[out] section_offset - The start of the requested section 686 * @param[out] section_length - The length of the requested section 687 * @return pldm_completion_codes 688 */ 689 int decode_multipart_receive_req(const struct pldm_msg *msg, 690 size_t payload_length, uint8_t *pldm_type, 691 uint8_t *transfer_opflag, 692 uint32_t *transfer_ctx, 693 uint32_t *transfer_handle, 694 uint32_t *section_offset, 695 uint32_t *section_length); 696 697 /** @brief Encode a PLDM MultipartReceive request message 698 * 699 * @param[in] instance_id - Message's instance id 700 * @param[in] req - The pointer to the request message to be encoded 701 * @param[in,out] msg - Message will be written to this 702 * @param[in] payload_length - length of request message payload 703 * @return 0 on success 704 * -EINVAL if the input parameters' memory are not allocated, 705 * or message type or instance in request header is invalid 706 * -ENOMSG if the PLDM type in the request header is invalid 707 * -EOVERFLOW if the input message length is invalid 708 */ 709 int encode_base_multipart_receive_req( 710 uint8_t instance_id, const struct pldm_multipart_receive_req *req, 711 struct pldm_msg *msg, size_t payload_length); 712 713 /** @brief Decode a PLDM MultipartReceive response message 714 * 715 * @param[in] msg - Response message 716 * @param[in] payload_length - length of request message payload 717 * @param[out] resp - pointer to the decoded response message, 718 * excluding the data integrity checksum 719 * @param[out] data_integrity_checksum - The checksum of data field 720 * of the decoded response message 721 * @return 0 on success 722 * -EINVAL if the input parameters' memory are not allocated 723 * -EOVERFLOW if the input message buffer is too short for the output 724 * response struct 725 * -EBADMSG if the input message buffer is too large for the output 726 * response struct 727 * @note Caller is responsible for memory alloc and dealloc of param 728 * 'msg.payload' 729 */ 730 int decode_base_multipart_receive_resp(const struct pldm_msg *msg, 731 size_t payload_length, 732 struct pldm_multipart_receive_resp *resp, 733 uint32_t *data_integrity_checksum); 734 735 /** @brief Create a PLDM response message containing only cc 736 * 737 * @param[in] instance_id - Message's instance id 738 * @param[in] type - PLDM Type 739 * @param[in] command - PLDM Command 740 * @param[in] cc - PLDM Completion Code 741 * @param[out] msg - Message will be written to this 742 * @return pldm_completion_codes 743 */ 744 int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command, 745 uint8_t cc, struct pldm_msg *msg); 746 747 /** @brief Create a PLDM message only with the header 748 * 749 * @param[in] msg_type - PLDM message type 750 * @param[in] instance_id - Message's instance id 751 * @param[in] pldm_type - PLDM Type 752 * @param[in] command - PLDM Command 753 * @param[out] msg - Message will be written to this 754 * 755 * @return pldm_completion_codes 756 */ 757 int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id, 758 uint8_t pldm_type, uint8_t command, 759 struct pldm_msg *msg); 760 761 /** @brief Encode a PLDM Negotiate Transfer Parameters request message 762 * 763 * @param[in] instance_id - Message's instance id 764 * @param[in] req - The pointer to the request message to be encoded 765 * @param[in,out] msg - Message will be written to this 766 * @param[in] payload_length - length of request message payload 767 * @return 0 on success 768 * -EINVAL if the input parameters' memory are not allocated, 769 * or message type or instance in request header is invalid 770 * -ENOMSG if the PLDM type in the request header is invalid 771 * -EOVERFLOW if the input message length is invalid 772 */ 773 int encode_pldm_base_negotiate_transfer_params_req( 774 uint8_t instance_id, 775 const struct pldm_base_negotiate_transfer_params_req *req, 776 struct pldm_msg *msg, size_t payload_length); 777 778 /** @brief Decode a PLDM Negotiate Transfer Parameters response message 779 * 780 * @param[in] msg - Response message 781 * @param[in] payload_length - length of request message payload 782 * @param[out] resp - pointer to the decoded response message, 783 * excluding the data integrity checksum 784 * @return 0 on success 785 * -EINVAL if the input parameters' memory are not allocated 786 * -EOVERFLOW if the input message buffer is too short for the output 787 * response struct 788 * -EBADMSG if the input message buffer is too large for the output 789 * response struct 790 * @note Caller is responsible for memory alloc and dealloc of param 791 * 'msg.payload' 792 */ 793 int decode_pldm_base_negotiate_transfer_params_resp( 794 const struct pldm_msg *msg, size_t payload_length, 795 struct pldm_base_negotiate_transfer_params_resp *resp); 796 797 #ifdef __cplusplus 798 } 799 #endif 800 801 #endif /* BASE_H */ 802