Define pldm data types

This commit defines some data types as per PLDM DSP0240. Only types that
are used are defined.

Change-Id: Id932d638587b4b34c2941d6d0714cd0e1f1be264
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/libpldm/base.c b/libpldm/base.c
index 8d336e5..3aca2c3 100644
--- a/libpldm/base.c
+++ b/libpldm/base.c
@@ -77,8 +77,8 @@
 	return PLDM_SUCCESS;
 }
 
-int encode_get_commands_req(uint8_t instance_id, uint8_t type,
-			    struct pldm_version version, struct pldm_msg *msg)
+int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version,
+			    struct pldm_msg *msg)
 {
 	if (msg == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
@@ -99,7 +99,7 @@
 }
 
 int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
-			  const uint8_t *types, struct pldm_msg *msg)
+			  const bitfield8_t *types, struct pldm_msg *msg)
 {
 	if (msg == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
@@ -118,14 +118,14 @@
 			return PLDM_ERROR_INVALID_DATA;
 		}
 		uint8_t *dst = msg->body.payload + sizeof(msg->body.payload[0]);
-		memcpy(dst, types, PLDM_MAX_TYPES / 8);
+		memcpy(dst, &(types->byte), PLDM_MAX_TYPES / 8);
 	}
 
 	return PLDM_SUCCESS;
 }
 
 int decode_get_commands_req(const struct pldm_msg_payload *msg, uint8_t *type,
-			    struct pldm_version *version)
+			    ver32_t *version)
 {
 	if (msg == NULL || type == NULL || version == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
@@ -133,14 +133,13 @@
 
 	const uint8_t *start = msg->payload;
 	*type = *start;
-	memcpy(version, (struct pldm_version *)(start + sizeof(*type)),
-	       sizeof(*version));
+	memcpy(version, (ver32_t *)(start + sizeof(*type)), sizeof(*version));
 
 	return PLDM_SUCCESS;
 }
 
 int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
-			     const uint8_t *commands, struct pldm_msg *msg)
+			     const bitfield8_t *commands, struct pldm_msg *msg)
 {
 	if (msg == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
@@ -159,31 +158,32 @@
 			return PLDM_ERROR_INVALID_DATA;
 		}
 		uint8_t *dst = msg->body.payload + sizeof(msg->body.payload[0]);
-		memcpy(dst, commands, PLDM_MAX_CMDS_PER_TYPE / 8);
+		memcpy(dst, &(commands->byte), PLDM_MAX_CMDS_PER_TYPE / 8);
 	}
 
 	return PLDM_SUCCESS;
 }
 
-int decode_get_types_resp(const struct pldm_msg_payload *msg, uint8_t *types)
+int decode_get_types_resp(const struct pldm_msg_payload *msg,
+			  bitfield8_t *types)
 {
 	if (msg == NULL || types == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
 	}
 	const uint8_t *src = msg->payload + sizeof(uint8_t);
-	memcpy(types, src, PLDM_MAX_TYPES / 8);
+	memcpy(&(types->byte), src, PLDM_MAX_TYPES / 8);
 
 	return PLDM_SUCCESS;
 }
 
 int decode_get_commands_resp(const struct pldm_msg_payload *msg,
-			     uint8_t *commands)
+			     bitfield8_t *commands)
 {
 	if (msg == NULL || commands == NULL) {
 		return PLDM_ERROR_INVALID_DATA;
 	}
 	const uint8_t *src = msg->payload + sizeof(uint8_t);
-	memcpy(commands, src, PLDM_MAX_CMDS_PER_TYPE / 8);
+	memcpy(&(commands->byte), src, PLDM_MAX_CMDS_PER_TYPE / 8);
 
 	return PLDM_SUCCESS;
 }
@@ -223,8 +223,7 @@
 
 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,
+			    uint8_t transfer_flag, const ver32_t *version_data,
 			    size_t version_size, struct pldm_msg *msg)
 {
 	struct pldm_header_info header = {0};
@@ -271,16 +270,14 @@
 
 int decode_get_version_resp(const struct pldm_msg_payload *msg,
 			    uint32_t *next_transfer_handle,
-			    uint8_t *transfer_flag,
-			    struct pldm_version *version)
+			    uint8_t *transfer_flag, ver32_t *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)));
+	*version = *((ver32_t *)(start + sizeof(*next_transfer_handle) +
+				 sizeof(*transfer_flag)));
 
 	return PLDM_SUCCESS;
 }
diff --git a/libpldm/base.h b/libpldm/base.h
index b2050a5..e0362f4 100644
--- a/libpldm/base.h
+++ b/libpldm/base.h
@@ -9,6 +9,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "pldm_types.h"
+
 /** @brief PLDM Types
  */
 enum pldm_supported_types {
@@ -117,17 +119,6 @@
 	struct pldm_msg_payload body; //!< PLDM message payload
 } __attribute__((packed));
 
-/** @struct pldm_version
- *
- * Structure representing PLDM ver32 type
- */
-struct pldm_version {
-	uint8_t major;
-	uint8_t minor;
-	uint8_t update;
-	uint8_t alpha;
-} __attribute__((packed));
-
 /** @struct pldm_header_info
  *
  *  The information needed to prepare PLDM header and this is passed to the
@@ -182,11 +173,12 @@
 /** @brief Decode a GetPLDMTypes response message
  *
  *  @param[in] msg - Response message payload
- *  @param[out] types - pointer to array uint8_t[8] containing supported
+ *  @param[out] types - pointer to array bitfield8_t[8] containing supported
  *              types (MAX_TYPES/8) = 8), as per DSP0240
  *  @return pldm_completion_codes
  */
-int decode_get_types_resp(const struct pldm_msg_payload *msg, uint8_t *types);
+int decode_get_types_resp(const struct pldm_msg_payload *msg,
+			  bitfield8_t *types);
 
 /* GetPLDMCommands */
 
@@ -200,18 +192,18 @@
  *  @note  Caller is responsible for memory alloc and dealloc of param
  *         'msg.body.payload'
  */
-int encode_get_commands_req(uint8_t instance_id, uint8_t type,
-			    struct pldm_version version, struct pldm_msg *msg);
+int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version,
+			    struct pldm_msg *msg);
 
 /** @brief Decode a GetPLDMCommands response message
  *
  *  @param[in] msg - Response message payload
- *  @param[in] commands - pointer to array uint8_t[32] containing supported
+ *  @param[in] commands - pointer to array bitfield8_t[32] containing supported
  *             commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
  *  @return pldm_completion_codes
  */
 int decode_get_commands_resp(const struct pldm_msg_payload *msg,
-			     uint8_t *commands);
+			     bitfield8_t *commands);
 
 /* GetPLDMVersion */
 
@@ -242,8 +234,7 @@
  */
 int decode_get_version_resp(const struct pldm_msg_payload *msg,
 			    uint32_t *next_transfer_handle,
-			    uint8_t *transfer_flag,
-			    struct pldm_version *version);
+			    uint8_t *transfer_flag, ver32_t *version);
 
 /* Responder */
 
@@ -253,7 +244,7 @@
  *
  *  @param[in] instance_id - Message's instance id
  *  @param[in] completion_code - PLDM completion code
- *  @param[in] types - pointer to array uint8_t[8] containing supported
+ *  @param[in] types - pointer to array bitfield8_t[8] containing supported
  *             types (MAX_TYPES/8) = 8), as per DSP0240
  *  @param[in,out] msg - Message will be written to this
  *  @return pldm_completion_codes
@@ -261,7 +252,7 @@
  *         'msg.body.payload'
  */
 int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
-			  const uint8_t *types, struct pldm_msg *msg);
+			  const bitfield8_t *types, struct pldm_msg *msg);
 
 /* GetPLDMCommands */
 
@@ -273,13 +264,13 @@
  *  @return pldm_completion_codes
  */
 int decode_get_commands_req(const struct pldm_msg_payload *msg, uint8_t *type,
-			    struct pldm_version *version);
+			    ver32_t *version);
 
 /** @brief Create a PLDM response message for GetPLDMCommands
  *
  *  @param[in] instance_id - Message's instance id
  *  @param[in] completion_code - PLDM completion code
- *  @param[in] commands - pointer to array uint8_t[32] containing supported
+ *  @param[in] commands - pointer to array bitfield8_t[32] containing supported
  *             commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
  *  @param[in,out] msg - Message will be written to this
  *  @return pldm_completion_codes
@@ -287,7 +278,7 @@
  *         'msg.body.payload'
  */
 int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
-			     const uint8_t *commands, struct pldm_msg *msg);
+			     const bitfield8_t *commands, struct pldm_msg *msg);
 
 /* GetPLDMVersion */
 
@@ -307,8 +298,7 @@
  */
 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,
+			    uint8_t transfer_flag, const ver32_t *version_data,
 			    size_t version_size, struct pldm_msg *msg);
 
 /** @brief Decode a GetPLDMVersion request message
diff --git a/libpldm/pldm_types.h b/libpldm/pldm_types.h
new file mode 100644
index 0000000..32228d7
--- /dev/null
+++ b/libpldm/pldm_types.h
@@ -0,0 +1,25 @@
+#include <stdint.h>
+
+typedef union {
+	uint8_t byte;
+	struct {
+		uint8_t bit0 : 1;
+		uint8_t bit1 : 1;
+		uint8_t bit2 : 1;
+		uint8_t bit3 : 1;
+		uint8_t bit5 : 1;
+		uint8_t bit6 : 1;
+		uint8_t bit7 : 1;
+	} __attribute__((packed)) bits;
+} bitfield8_t;
+
+/** @struct pldm_version
+ *
+ *
+ */
+typedef struct pldm_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t update;
+	uint8_t alpha;
+} __attribute__((packed)) ver32_t;
diff --git a/libpldmresponder/base.cpp b/libpldmresponder/base.cpp
index 9489d47..6ae8ba6 100644
--- a/libpldmresponder/base.cpp
+++ b/libpldmresponder/base.cpp
@@ -18,20 +18,20 @@
 static const std::map<Type, Cmd> capabilities{
     {PLDM_BASE, {PLDM_GET_PLDM_TYPES, PLDM_GET_PLDM_COMMANDS}}};
 
-static const std::map<Type, pldm_version> versions{
+static const std::map<Type, ver32_t> versions{
     {PLDM_BASE, {0xF1, 0xF0, 0xF0, 0x00}},
 };
 
 void getPLDMTypes(const pldm_msg_payload* request, pldm_msg* response)
 {
     // DSP0240 has this as a bitfield8[N], where N = 0 to 7
-    std::array<uint8_t, 8> types{};
+    std::array<bitfield8_t, 8> types{};
     for (const auto& type : capabilities)
     {
         auto index = type.first / 8;
         // <Type Number> = <Array Index> * 8 + <bit position>
         auto bit = type.first - (index * 8);
-        types[index] |= 1 << bit;
+        types[index].byte |= 1 << bit;
     }
 
     encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response);
@@ -39,7 +39,7 @@
 
 void getPLDMCommands(const pldm_msg_payload* request, pldm_msg* response)
 {
-    pldm_version version{};
+    ver32_t version{};
     Type type;
 
     if (request->payload_length != (sizeof(version) + sizeof(type)))
@@ -52,7 +52,7 @@
     decode_get_commands_req(request, &type, &version);
 
     // DSP0240 has this as a bitfield8[N], where N = 0 to 31
-    std::array<uint8_t, 32> cmds{};
+    std::array<bitfield8_t, 32> cmds{};
     if (capabilities.find(type) == capabilities.end())
     {
         encode_get_commands_resp(0, PLDM_ERROR_INVALID_PLDM_TYPE, nullptr,
@@ -65,7 +65,7 @@
         auto index = cmd / 8;
         // <Type Number> = <Array Index> * 8 + <bit position>
         auto bit = cmd - (index * 8);
-        cmds[index] |= 1 << bit;
+        cmds[index].byte |= 1 << bit;
     }
 
     encode_get_commands_resp(0, PLDM_SUCCESS, cmds.data(), response);
@@ -87,7 +87,7 @@
 
     decode_get_version_req(request, &transferHandle, &transferFlag, &type);
 
-    pldm_version version{};
+    ver32_t version{};
     auto search = versions.find(type);
 
     if (search == versions.end())
diff --git a/test/libpldm_base_test.cpp b/test/libpldm_base_test.cpp
index 9a37ec6..24ad513 100644
--- a/test/libpldm_base_test.cpp
+++ b/test/libpldm_base_test.cpp
@@ -190,7 +190,7 @@
 TEST(GetPLDMCommands, testEncodeRequest)
 {
     uint8_t pldmType = 0x05;
-    pldm_version version{0xFF, 0xFF, 0xFF, 0xFF};
+    ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
     std::array<uint8_t, PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{};
     pldm_msg request{};
     request.body.payload = requestMsg.data();
@@ -206,9 +206,9 @@
 TEST(GetPLDMCommands, testDecodeRequest)
 {
     uint8_t pldmType = 0x05;
-    pldm_version version{0xFF, 0xFF, 0xFF, 0xFF};
+    ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
     uint8_t pldmTypeOut{};
-    pldm_version versionOut{0xFF, 0xFF, 0xFF, 0xFF};
+    ver32_t versionOut{0xFF, 0xFF, 0xFF, 0xFF};
     std::array<uint8_t, PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{};
     pldm_msg_payload request{};
     request.payload = requestMsg.data();
@@ -229,10 +229,10 @@
     pldm_msg response{};
     response.body.payload = responseMsg.data();
     response.body.payload_length = responseMsg.size();
-    std::array<uint8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{};
-    commands[0] = 1;
-    commands[1] = 2;
-    commands[2] = 3;
+    std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{};
+    commands[0].byte = 1;
+    commands[1].byte = 2;
+    commands[2].byte = 3;
 
     auto rc =
         encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), &response);
@@ -250,10 +250,10 @@
     pldm_msg response{};
     response.body.payload = responseMsg.data();
     response.body.payload_length = responseMsg.size();
-    std::array<uint8_t, PLDM_MAX_TYPES / 8> types{};
-    types[0] = 1;
-    types[1] = 2;
-    types[2] = 3;
+    std::array<bitfield8_t, PLDM_MAX_TYPES / 8> types{};
+    types[0].byte = 1;
+    types[1].byte = 2;
+    types[2].byte = 3;
 
     auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), &response);
     ASSERT_EQ(rc, PLDM_SUCCESS);
@@ -272,14 +272,14 @@
     response.payload[1] = 1;
     response.payload[2] = 2;
     response.payload[3] = 3;
-    std::array<uint8_t, PLDM_MAX_TYPES / 8> outTypes{};
+    std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
 
     auto rc = decode_get_types_resp(&response, outTypes.data());
 
     ASSERT_EQ(rc, PLDM_SUCCESS);
-    ASSERT_EQ(response.payload[1], outTypes[0]);
-    ASSERT_EQ(response.payload[2], outTypes[1]);
-    ASSERT_EQ(response.payload[3], outTypes[2]);
+    ASSERT_EQ(response.payload[1], outTypes[0].byte);
+    ASSERT_EQ(response.payload[2], outTypes[1].byte);
+    ASSERT_EQ(response.payload[3], outTypes[2].byte);
 }
 
 TEST(GetPLDMCommands, testDecodeResponse)
@@ -291,14 +291,14 @@
     response.payload[1] = 1;
     response.payload[2] = 2;
     response.payload[3] = 3;
-    std::array<uint8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
+    std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
 
     auto rc = decode_get_commands_resp(&response, outTypes.data());
 
     ASSERT_EQ(rc, PLDM_SUCCESS);
-    ASSERT_EQ(response.payload[1], outTypes[0]);
-    ASSERT_EQ(response.payload[2], outTypes[1]);
-    ASSERT_EQ(response.payload[3], outTypes[2]);
+    ASSERT_EQ(response.payload[1], outTypes[0].byte);
+    ASSERT_EQ(response.payload[2], outTypes[1].byte);
+    ASSERT_EQ(response.payload[3], outTypes[2].byte);
 }
 
 TEST(GetPLDMVersion, testEncodeRequest)
@@ -332,11 +332,10 @@
     std::array<uint8_t, PLDM_GET_VERSION_RESP_BYTES> responseMsg{};
     response.body.payload = responseMsg.data();
     response.body.payload_length = responseMsg.size();
-    struct pldm_version version = {0xFF, 0xFF, 0xFF, 0xFF};
+    ver32_t version = {0xFF, 0xFF, 0xFF, 0xFF};
 
-    auto rc =
-        encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END,
-                                &version, sizeof(pldm_version), &response);
+    auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END,
+                                      &version, sizeof(ver32_t), &response);
 
     ASSERT_EQ(rc, PLDM_SUCCESS);
     ASSERT_EQ(completionCode, response.body.payload[0]);
@@ -391,8 +390,8 @@
     uint8_t flag = PLDM_START_AND_END;
     uint8_t retFlag = PLDM_START_AND_END;
     uint8_t completionCode = 0;
-    struct pldm_version version = {0xFF, 0xFF, 0xFF, 0xFF};
-    struct pldm_version versionOut;
+    ver32_t version = {0xFF, 0xFF, 0xFF, 0xFF};
+    ver32_t versionOut;
 
     memcpy(response.payload + sizeof(completionCode), &transferHandle,
            sizeof(transferHandle));
diff --git a/test/libpldmresponder_base_test.cpp b/test/libpldmresponder_base_test.cpp
index a34d80f..b9ef717 100644
--- a/test/libpldmresponder_base_test.cpp
+++ b/test/libpldmresponder_base_test.cpp
@@ -73,7 +73,7 @@
     uint32_t transferHandle = 0x0;
     uint8_t flag = PLDM_GET_FIRSTPART;
     uint8_t retFlag = PLDM_START_AND_END;
-    struct pldm_version version = {0xF1, 0xF0, 0xF0, 0x00};
+    ver32_t version = {0xF1, 0xF0, 0xF0, 0x00};
 
     auto rc =
         encode_get_version_req(0, transferHandle, flag, pldmType, &request);