Implement buildFileTable interface

The buildFileTable interface will be used by the ReadFileIntoMemory
and WriteFileFromMemory commands to get the file table and map the
file handle to the file path.

Change-Id: Ibdc01737d8925ef918c4fbe2919108d96a2807ab
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/test/libpldmresponder_fileio_test.cpp b/test/libpldmresponder_fileio_test.cpp
index 424e09c..2c5f90e 100644
--- a/test/libpldmresponder_fileio_test.cpp
+++ b/test/libpldmresponder_fileio_test.cpp
@@ -233,6 +233,118 @@
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
 }
 
+TEST_F(TestFileTable, ReadFileInvalidFileHandle)
+{
+    // Invalid file handle in the file table
+    uint32_t fileHandle = 2;
+    uint32_t offset = 0;
+    uint32_t length = 0;
+    uint64_t address = 0;
+
+    std::array<uint8_t, PLDM_RW_FILE_MEM_REQ_BYTES> requestMsg{};
+    memcpy(requestMsg.data(), &fileHandle, sizeof(fileHandle));
+    memcpy(requestMsg.data() + sizeof(fileHandle), &offset, sizeof(offset));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset), &length,
+           sizeof(length));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset) +
+               sizeof(length),
+           &address, sizeof(address));
+
+    using namespace pldm::filetable;
+    // Initialise the file table with 2 valid file handles 0 & 1.
+    auto& table = buildFileTable(fileTableConfig.c_str());
+
+    auto response = readFileIntoMemory(requestMsg.data(), requestMsg.size());
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
+    // Clear the file table contents.
+    table.clear();
+}
+
+TEST_F(TestFileTable, ReadFileInvalidOffset)
+{
+    uint32_t fileHandle = 0;
+    // The file size is 1024, so the offset is invalid
+    uint32_t offset = 1024;
+    uint32_t length = 0;
+    uint64_t address = 0;
+
+    std::array<uint8_t, PLDM_RW_FILE_MEM_REQ_BYTES> requestMsg{};
+    memcpy(requestMsg.data(), &fileHandle, sizeof(fileHandle));
+    memcpy(requestMsg.data() + sizeof(fileHandle), &offset, sizeof(offset));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset), &length,
+           sizeof(length));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset) +
+               sizeof(length),
+           &address, sizeof(address));
+
+    using namespace pldm::filetable;
+    auto& table = buildFileTable(fileTableConfig.c_str());
+
+    auto response = readFileIntoMemory(requestMsg.data(), requestMsg.size());
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
+    // Clear the file table contents.
+    table.clear();
+}
+
+TEST_F(TestFileTable, ReadFileInvalidLength)
+{
+    uint32_t fileHandle = 0;
+    uint32_t offset = 100;
+    // Length should be a multiple of dma min size(16)
+    uint32_t length = 10;
+    uint64_t address = 0;
+
+    std::array<uint8_t, PLDM_RW_FILE_MEM_REQ_BYTES> requestMsg{};
+    memcpy(requestMsg.data(), &fileHandle, sizeof(fileHandle));
+    memcpy(requestMsg.data() + sizeof(fileHandle), &offset, sizeof(offset));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset), &length,
+           sizeof(length));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset) +
+               sizeof(length),
+           &address, sizeof(address));
+
+    using namespace pldm::filetable;
+    auto& table = buildFileTable(fileTableConfig.c_str());
+
+    auto response = readFileIntoMemory(requestMsg.data(), requestMsg.size());
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH);
+    // Clear the file table contents.
+    table.clear();
+}
+
+TEST_F(TestFileTable, ReadFileInvalidEffectiveLength)
+{
+    uint32_t fileHandle = 0;
+    // valid offset
+    uint32_t offset = 100;
+    // length + offset exceeds the size, so effective length is
+    // filesize(1024) - offset(100). The effective length is not a multiple of
+    // DMA min size(16)
+    uint32_t length = 1024;
+    uint64_t address = 0;
+
+    std::array<uint8_t, PLDM_RW_FILE_MEM_REQ_BYTES> requestMsg{};
+    memcpy(requestMsg.data(), &fileHandle, sizeof(fileHandle));
+    memcpy(requestMsg.data() + sizeof(fileHandle), &offset, sizeof(offset));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset), &length,
+           sizeof(length));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset) +
+               sizeof(length),
+           &address, sizeof(address));
+
+    using namespace pldm::filetable;
+    auto& table = buildFileTable(fileTableConfig.c_str());
+
+    auto response = readFileIntoMemory(requestMsg.data(), requestMsg.size());
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH);
+    // Clear the file table contents.
+    table.clear();
+}
+
 TEST(WriteFileFromMemory, BadPath)
 {
     uint32_t fileHandle = 0;
@@ -260,6 +372,62 @@
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_WRITE_LENGTH);
 }
 
+TEST_F(TestFileTable, WriteFileInvalidFileHandle)
+{
+    // Invalid file handle in the file table
+    uint32_t fileHandle = 2;
+    uint32_t offset = 0;
+    uint32_t length = 16;
+    uint64_t address = 0;
+
+    std::array<uint8_t, PLDM_RW_FILE_MEM_REQ_BYTES> requestMsg{};
+    memcpy(requestMsg.data(), &fileHandle, sizeof(fileHandle));
+    memcpy(requestMsg.data() + sizeof(fileHandle), &offset, sizeof(offset));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset), &length,
+           sizeof(length));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset) +
+               sizeof(length),
+           &address, sizeof(address));
+
+    using namespace pldm::filetable;
+    // Initialise the file table with 2 valid file handles 0 & 1.
+    auto& table = buildFileTable(fileTableConfig.c_str());
+
+    auto response = writeFileFromMemory(requestMsg.data(), requestMsg.size());
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
+    // Clear the file table contents.
+    table.clear();
+}
+
+TEST_F(TestFileTable, WriteFileInvalidOffset)
+{
+    uint32_t fileHandle = 0;
+    // The file size is 1024, so the offset is invalid
+    uint32_t offset = 1024;
+    uint32_t length = 16;
+    uint64_t address = 0;
+
+    std::array<uint8_t, PLDM_RW_FILE_MEM_REQ_BYTES> requestMsg{};
+    memcpy(requestMsg.data(), &fileHandle, sizeof(fileHandle));
+    memcpy(requestMsg.data() + sizeof(fileHandle), &offset, sizeof(offset));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset), &length,
+           sizeof(length));
+    memcpy(requestMsg.data() + sizeof(fileHandle) + sizeof(offset) +
+               sizeof(length),
+           &address, sizeof(address));
+
+    using namespace pldm::filetable;
+    // Initialise the file table with 2 valid file handles 0 & 1.
+    auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str());
+
+    auto response = writeFileFromMemory(requestMsg.data(), requestMsg.size());
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
+    // Clear the file table contents.
+    table.clear();
+}
+
 TEST(FileTable, ConfigNotExist)
 {
     logs.clear();