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