Implement GetPLDMVersion command
This commit implements the GetPLDMVersion which is required
as part of the base PLDM support to know the version of a
given PLDM type.
Change-Id: I1bcbd938c5b6833f62e0ee2f474b04d76b6970d9
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/libpldm/base.c b/libpldm/base.c
index c85aead..7354fb1 100644
--- a/libpldm/base.c
+++ b/libpldm/base.c
@@ -161,3 +161,100 @@
return PLDM_SUCCESS;
}
+
+int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
+ uint8_t transfer_opflag, uint8_t type,
+ struct pldm_msg *msg)
+{
+ struct pldm_header_info header = {0};
+ int rc = PLDM_SUCCESS;
+
+ if (NULL == msg) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ header.msg_type = PLDM_REQUEST;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_BASE;
+ header.command = PLDM_GET_PLDM_VERSION;
+
+ if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
+ return rc;
+ }
+
+ uint8_t *dst = msg->body.payload;
+ transfer_handle = htole32(transfer_handle);
+ memcpy(dst, &transfer_handle, sizeof(transfer_handle));
+ dst += sizeof(transfer_handle);
+
+ memcpy(dst, &transfer_opflag, sizeof(transfer_opflag));
+ dst += sizeof(transfer_opflag);
+
+ memcpy(dst, &type, sizeof(type));
+
+ return PLDM_SUCCESS;
+}
+
+int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
+ uint32_t next_transfer_handle,
+ uint8_t transfer_flag,
+ const struct pldm_version *version_data,
+ size_t version_size, struct pldm_msg *msg)
+{
+ struct pldm_header_info header = {0};
+ int rc = PLDM_SUCCESS;
+
+ msg->body.payload[0] = completion_code;
+ if (msg->body.payload[0] == PLDM_SUCCESS) {
+
+ header.msg_type = PLDM_RESPONSE;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_BASE;
+ header.command = PLDM_GET_PLDM_VERSION;
+
+ if ((rc = pack_pldm_header(&header, &(msg->hdr))) >
+ PLDM_SUCCESS) {
+ return rc;
+ }
+ uint8_t *dst = msg->body.payload + sizeof(msg->body.payload[0]);
+
+ next_transfer_handle = htole32(next_transfer_handle);
+
+ memcpy(dst, &next_transfer_handle,
+ sizeof(next_transfer_handle));
+ dst += sizeof(next_transfer_handle);
+ memcpy(dst, &transfer_flag, sizeof(transfer_flag));
+
+ dst += sizeof(transfer_flag);
+ memcpy(dst, version_data, version_size);
+ }
+ return PLDM_SUCCESS;
+}
+
+int decode_get_version_req(const struct pldm_msg_payload *msg,
+ uint32_t *transfer_handle, uint8_t *transfer_opflag,
+ uint8_t *type)
+{
+ const uint8_t *start = msg->payload;
+ *transfer_handle = le32toh(*((uint32_t *)start));
+ *transfer_opflag = *(start + sizeof(*transfer_handle));
+ *type = *(start + sizeof(*transfer_handle) + sizeof(*transfer_opflag));
+
+ return PLDM_SUCCESS;
+}
+
+int decode_get_version_resp(const struct pldm_msg_payload *msg,
+ uint32_t *next_transfer_handle,
+ uint8_t *transfer_flag,
+ struct pldm_version *version)
+{
+ const uint8_t *start = msg->payload + sizeof(uint8_t);
+ *next_transfer_handle = le32toh(*((uint32_t *)start));
+ *transfer_flag = *(start + sizeof(*next_transfer_handle));
+
+ *version =
+ *((struct pldm_version *)(start + sizeof(*next_transfer_handle) +
+ sizeof(*transfer_flag)));
+
+ return PLDM_SUCCESS;
+}
diff --git a/libpldm/base.h b/libpldm/base.h
index 65be648..b2050a5 100644
--- a/libpldm/base.h
+++ b/libpldm/base.h
@@ -18,6 +18,7 @@
/** @brief PLDM Commands
*/
enum pldm_supported_commands {
+ PLDM_GET_PLDM_VERSION = 0x3,
PLDM_GET_PLDM_TYPES = 0x4,
PLDM_GET_PLDM_COMMANDS = 0x5
};
@@ -34,6 +35,18 @@
PLDM_ERROR_INVALID_PLDM_TYPE = 0x20
};
+enum transfer_op_flag {
+ PLDM_GET_NEXTPART = 0,
+ PLDM_GET_FIRSTPART = 1,
+};
+
+enum transfer_resp_flag {
+ PLDM_START = 0x01,
+ PLDM_MIDDLE = 0x02,
+ PLDM_END = 0x04,
+ PLDM_START_AND_END = 0x05,
+};
+
/** @enum MessageType
*
* The different message types supported by the PLDM specification.
@@ -51,10 +64,13 @@
/* Message payload lengths */
#define PLDM_GET_COMMANDS_REQ_BYTES 5
+#define PLDM_GET_VERSION_REQ_BYTES 6
/* Response lengths are inclusive of completion code */
#define PLDM_GET_TYPES_RESP_BYTES 9
#define PLDM_GET_COMMANDS_RESP_BYTES 33
+/* Response data has only one version and does not contain the checksum */
+#define PLDM_GET_VERSION_RESP_BYTES 10
/** @struct pldm_msg_hdr
*
@@ -197,6 +213,38 @@
int decode_get_commands_resp(const struct pldm_msg_payload *msg,
uint8_t *commands);
+/* GetPLDMVersion */
+
+/** @brief Create a PLDM request for GetPLDMVersion
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] transfer_handle - Handle to identify PLDM version data transfer.
+ * This handle is ignored by the responder when the
+ * transferop_flag is set to getFirstPart.
+ * @param[in] transfer_opflag - flag to indicate whether it is start of
+ * transfer
+ * @param[in] type - PLDM Type for which version is requested
+ * @param[in,out] msg - Message will be written to this
+ * @return pldm_completion_codes
+ * @note Caller is responsible for memory alloc and dealloc of param
+ * 'msg.body.payload'
+ */
+int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
+ uint8_t transfer_opflag, uint8_t type,
+ struct pldm_msg *msg);
+
+/** @brief Decode a GetPLDMVersion response message
+ *
+ * @param[in] msg - Response message payload
+ * @param[out] next_transfer_handle - the next handle for the next part of data
+ * @param[out] transfer_flag - flag to indicate the part of data
+ * @return pldm_completion_codes
+ */
+int decode_get_version_resp(const struct pldm_msg_payload *msg,
+ uint32_t *next_transfer_handle,
+ uint8_t *transfer_flag,
+ struct pldm_version *version);
+
/* Responder */
/* GetPLDMTypes */
@@ -241,6 +289,40 @@
int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
const uint8_t *commands, struct pldm_msg *msg);
+/* GetPLDMVersion */
+
+/** @brief Create a PLDM response for GetPLDMVersion
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] completion_code - PLDM completion code
+ * @param[in] next_transfer_handle - Handle to identify next portion of
+ * data transfer
+ * @param[in] transfer_flag - Represents the part of transfer
+ * @param[in] version_data - the version data
+ * @param[in] version_size - size of version data
+ * @param[in,out] msg - Message will be written to this
+ * @return pldm_completion_codes
+ * @note Caller is responsible for memory alloc and dealloc of param
+ * 'msg.body.payload'
+ */
+int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
+ uint32_t next_transfer_handle,
+ uint8_t transfer_flag,
+ const struct pldm_version *version_data,
+ size_t version_size, struct pldm_msg *msg);
+
+/** @brief Decode a GetPLDMVersion request message
+ *
+ * @param[in] msg - Request message payload
+ * @param[out] transfer_handle - the handle of data
+ * @param[out] transfer_opflag - Transfer Flag
+ * @param[out] type - PLDM type for which version is requested
+ * @return pldm_completion_codes
+ */
+int decode_get_version_req(const struct pldm_msg_payload *msg,
+ uint32_t *transfer_handle, uint8_t *transfer_opflag,
+ uint8_t *type);
+
#ifdef __cplusplus
}
#endif