GetBIOSTable responder implementation

This commit implements the GetBIOSTable responder handler
for the BIOS Enumeration type.
One of the tables among String table, Attribute table and Attribute
Value Table are created/fetched and sent to PLDM requester as response to
the command.

Tested:
Following are the tables constructed from the sample json file present at
"test/bios_jsons/enum_attrs.json"
-bash-4.2$ hexdump -C /tmp/AllBiosTables/stringTable
00000000  00 00 07 00 41 6c 6c 6f  77 65 64 01 00 10 00 43  |....Allowed....C|
00000010  6f 64 65 55 70 64 61 74  65 50 6f 6c 69 63 79 02  |odeUpdatePolicy.|
00000020  00 0a 00 43 6f 6e 63 75  72 72 65 6e 74 03 00 0a  |...Concurrent...|
00000030  00 44 69 73 72 75 70 74  69 76 65 04 00 0a 00 46  |.Disruptive....F|
00000040  57 42 6f 6f 74 53 69 64  65 05 00 0f 00 48 4d 43  |WBootSide....HMC|
00000050  4d 61 6e 61 67 65 64 53  74 61 74 65 06 00 10 00  |ManagedState....|
00000060  49 6e 62 61 6e 64 43 6f  64 65 55 70 64 61 74 65  |InbandCodeUpdate|
00000070  07 00 0a 00 4e 6f 74 41  6c 6c 6f 77 65 64 08 00  |....NotAllowed..|
00000080  03 00 4f 66 66 09 00 02  00 4f 6e 0a 00 04 00 50  |..Off....On....P|
00000090  65 72 6d 0b 00 04 00 54  65 6d 70 00 37 90 c0 da  |erm....Temp.7...|
000000a0
-bash-4.2$ hexdump -C /tmp/AllBiosTables/attributeTable
00000000  00 00 00 01 00 02 02 00  03 00 01 00 01 00 00 04  |................|
00000010  00 02 0a 00 0b 00 01 00  02 00 00 05 00 02 08 00  |................|
00000020  09 00 01 01 03 00 00 06  00 02 00 00 07 00 01 00  |................|
00000030  3b 85 69 a7                                       |;.i.|
00000034
-bash-4.2$ hexdump -C /tmp/AllBiosTables/attributeValueTable
00000000  00 00 00 01 00 00 00 00  d9 f6 42 58              |..........BX|
0000000c

Change-Id: I06aebcc2c2deea66e867fb775afa76a1e5d18dca
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/libpldm/bios.c b/libpldm/bios.c
index 9664318..3027f6c 100644
--- a/libpldm/bios.c
+++ b/libpldm/bios.c
@@ -86,3 +86,65 @@
 
 	return PLDM_SUCCESS;
 }
+
+int encode_get_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
+			       uint32_t next_transfer_handle,
+			       uint8_t transfer_flag, uint8_t *table_data,
+			       size_t payload_length, struct pldm_msg *msg)
+{
+	struct pldm_header_info header = {0};
+	int rc = PLDM_SUCCESS;
+
+	if (msg == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	struct pldm_get_bios_table_resp *response =
+	    (struct pldm_get_bios_table_resp *)msg->payload;
+
+	response->completion_code = completion_code;
+	header.msg_type = PLDM_RESPONSE;
+	header.instance = instance_id;
+	header.pldm_type = PLDM_BIOS;
+	header.command = PLDM_GET_BIOS_TABLE;
+	if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
+		return rc;
+	}
+
+	if (response->completion_code == PLDM_SUCCESS) {
+
+		response->next_transfer_handle = htole32(next_transfer_handle);
+		response->transfer_flag = transfer_flag;
+		if (table_data != NULL &&
+		    payload_length > (sizeof(struct pldm_msg_hdr) +
+				      PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES)) {
+			memcpy(response->table_data, table_data,
+			       payload_length -
+				   (sizeof(struct pldm_msg_hdr) +
+				    PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES));
+		}
+	}
+	return PLDM_SUCCESS;
+}
+
+int decode_get_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
+			      uint32_t *transfer_handle,
+			      uint8_t *transfer_op_flag, uint8_t *table_type)
+{
+	if (msg == NULL || transfer_op_flag == NULL || table_type == NULL ||
+	    transfer_handle == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	if (payload_length != PLDM_GET_BIOS_TABLE_REQ_BYTES) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	struct pldm_get_bios_table_req *request =
+	    (struct pldm_get_bios_table_req *)msg->payload;
+	*transfer_handle = le32toh(request->transfer_handle);
+	*transfer_op_flag = request->transfer_op_flag;
+	*table_type = request->table_type;
+
+	return PLDM_SUCCESS;
+}
diff --git a/libpldm/bios.h b/libpldm/bios.h
index 7030f5d..d8886c3 100644
--- a/libpldm/bios.h
+++ b/libpldm/bios.h
@@ -14,7 +14,18 @@
 /* Response lengths are inclusive of completion code */
 #define PLDM_GET_DATE_TIME_RESP_BYTES 8
 
-enum pldm_bios_commands { PLDM_GET_DATE_TIME = 0x0c };
+#define PLDM_GET_BIOS_TABLE_REQ_BYTES 6
+#define PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES 6
+
+enum pldm_bios_completion_codes {
+	PLDM_BIOS_TABLE_UNAVAILABLE = 0x83,
+	PLDM_INVALID_BIOS_TABLE_DATA_INTEGRITY_CHECK = 0x84,
+	PLDM_INVALID_BIOS_TABLE_TYPE = 0x85,
+};
+enum pldm_bios_commands {
+	PLDM_GET_BIOS_TABLE = 0x01,
+	PLDM_GET_DATE_TIME = 0x0c
+};
 
 enum pldm_bios_table_types {
 	PLDM_BIOS_STRING_TABLE,
@@ -46,6 +57,38 @@
 	uint8_t value[1];
 } __attribute__((packed));
 
+enum pldm_bios_attribute_type {
+	PLDM_BIOS_ENUMERATION = 0x0,
+	PLDM_BIOS_STRING = 0x1,
+	PLDM_BIOS_PASSWORD = 0x2,
+	PLDM_BIOS_INTEGER = 0x3,
+	PLDM_BIOS_ENUMERATION_READ_ONLY = 0x80,
+	PLDM_BIOS_STRING_READ_ONLY = 0x81,
+	PLDM_BIOS_PASSWORD_READ_ONLY = 0x82,
+	PLDM_BIOS_INTEGER_READ_ONLY = 0x83,
+};
+
+/** @struct pldm_get_bios_table_req
+ *
+ *  structure representing GetBIOSTable request packet
+ */
+struct pldm_get_bios_table_req {
+	uint32_t transfer_handle;
+	uint8_t transfer_op_flag;
+	uint8_t table_type;
+} __attribute__((packed));
+
+/** @struct pldm_get_bios_table_resp
+ *
+ *  structure representing GetBIOSTable response packet
+ */
+struct pldm_get_bios_table_resp {
+	uint8_t completion_code;
+	uint32_t next_transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t table_data[1];
+} __attribute__((packed));
+
 /** @struct pldm_get_date_time_resp
  *
  *  Structure representing PLDM get date time response
@@ -118,6 +161,40 @@
 			      uint8_t day, uint8_t month, uint16_t year,
 			      struct pldm_msg *msg);
 
+/* GetBIOSTable */
+
+/** @brief Create a PLDM response message for GetBIOSTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ * transfer
+ *  @param[in] transfer_flag - To indicate what part of the transfer this
+ * response represents
+ *  @param[in] table_data - BIOS Table type specific data
+ *  @param[in] payload_length - Length of payload message
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_get_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
+			       uint32_t next_transfer_handle,
+			       uint8_t transfer_flag, uint8_t *table_data,
+			       size_t payload_length, struct pldm_msg *msg);
+
+/** @brief Decode GetBIOSTable request packet
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[out] transfer_op_flag - Flag to indicate the start of a multipart
+ * transfer
+ *  @param[out] table_type - BIOS table type
+ *  @return pldm_completion_codes
+ */
+int decode_get_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
+			      uint32_t *transfer_handle,
+			      uint8_t *transfer_op_flag, uint8_t *table_type);
+
 #ifdef __cplusplus
 }
 #endif