Implement command GetDateTime

This commit implements the GetDateTime command which is
defined in PLDM Bios Control and Configuration Specification.

Change-Id: Iced21bbad7be07d357b6885b1b1e03b07a3da165
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index 7211573..ebbf363 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -5,7 +5,9 @@
 check_PROGRAMS = \
 	libpldm_base_test \
 	libpldm_platform_test \
-	libpldmresponder_base_test
+	libpldmresponder_base_test \
+	libpldm_bios_test \
+	libpldmresponder_bios_test
 
 test_cppflags = \
 	-Igtest \
@@ -37,6 +39,27 @@
 	$(CODE_COVERAGE_LIBS)
 libpldm_platform_test_SOURCES = libpldm_platform_test.cpp
 
+libpldm_bios_test_CPPFLAGS = $(test_cppflags)
+libpldm_bios_test_CXXFLAGS = $(test_cxxflags)
+libpldm_bios_test_LDFLAGS = $(test_ldflags)
+libpldm_bios_test_LDADD = \
+	$(top_builddir)/libpldm/libpldm_la-base.o  \
+	$(top_builddir)/libpldm/libpldm_la-bios.o \
+	$(CODE_COVERAGE_LIBS)
+libpldm_bios_test_SOURCES = libpldm_bios_test.cpp
+
+libpldmresponder_bios_test_CPPFLAGS = $(test_cppflags)
+libpldmresponder_bios_test_CXXFLAGS = $(test_cxxflags)
+libpldmresponder_bios_test_LDFLAGS = $(test_ldflags) $(SDBUSPLUS_LIBS)
+libpldmresponder_bios_test_LDADD = \
+	$(top_builddir)/libpldmresponder/libpldmresponder_la-bios.o \
+	$(top_builddir)/libpldmresponder/libpldmresponder_la-utils.o \
+	$(top_builddir)/libpldm/libpldm_la-base.o  \
+	$(top_builddir)/libpldm/libpldm_la-bios.o \
+	$(CODE_COVERAGE_LIBS) $(SDBUSPLUS_LIBS)
+libpldmresponder_bios_test_SOURCES = \
+	libpldmresponder_bios_test.cpp
+
 
 libpldmresponder_base_test_CPPFLAGS = $(test_cppflags)
 libpldmresponder_base_test_CXXFLAGS = $(test_cxxflags)
@@ -46,3 +69,4 @@
 	$(top_builddir)/libpldmresponder/libpldmresponder_la-base.o $(CODE_COVERAGE_LIBS)
 
 libpldmresponder_base_test_SOURCES = libpldmresponder_base_test.cpp
+
diff --git a/test/libpldm_bios_test.cpp b/test/libpldm_bios_test.cpp
new file mode 100644
index 0000000..b1771c9
--- /dev/null
+++ b/test/libpldm_bios_test.cpp
@@ -0,0 +1,118 @@
+#include <string.h>
+
+#include <array>
+
+#include "libpldm/base.h"
+#include "libpldm/bios.h"
+
+#include <gtest/gtest.h>
+
+TEST(GetDateTime, testEncodeRequest)
+{
+    pldm_msg request{};
+    request.body.payload = nullptr;
+    request.body.payload_length = 0;
+
+    auto rc = encode_get_date_time_req(0, &request);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+}
+
+TEST(GetDateTime, testEncodeResponse)
+{
+    uint8_t completionCode = 0;
+    uint8_t seconds = 50;
+    uint8_t minutes = 20;
+    uint8_t hours = 5;
+    uint8_t day = 23;
+    uint8_t month = 11;
+    uint16_t year = 2019;
+
+    std::array<uint8_t, PLDM_GET_DATE_TIME_RESP_BYTES> responseMsg{};
+    pldm_msg response{};
+
+    response.body.payload = responseMsg.data();
+    response.body.payload_length = responseMsg.size();
+
+    auto rc = encode_get_date_time_resp(0, PLDM_SUCCESS, seconds, minutes,
+                                        hours, day, month, year, &response);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(completionCode, response.body.payload[0]);
+
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]),
+                     &seconds, sizeof(seconds)));
+    ASSERT_EQ(0, memcmp(response.body.payload +
+                            sizeof(response.body.payload[0]) + sizeof(seconds),
+                        &minutes, sizeof(minutes)));
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]) +
+                         sizeof(seconds) + sizeof(minutes),
+                     &hours, sizeof(hours)));
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]) +
+                         sizeof(seconds) + sizeof(minutes) + sizeof(hours),
+                     &day, sizeof(day)));
+    ASSERT_EQ(0, memcmp(response.body.payload +
+                            sizeof(response.body.payload[0]) + sizeof(seconds) +
+                            sizeof(minutes) + sizeof(hours) + sizeof(day),
+                        &month, sizeof(month)));
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]) +
+                         sizeof(seconds) + sizeof(minutes) + sizeof(hours) +
+                         sizeof(day) + sizeof(month),
+                     &year, sizeof(year)));
+}
+
+TEST(GetDateTime, testDecodeResponse)
+{
+    std::array<uint8_t, PLDM_GET_DATE_TIME_RESP_BYTES> responseMsg{};
+    pldm_msg_payload response{};
+    response.payload = responseMsg.data();
+    response.payload_length = responseMsg.size();
+
+    uint8_t completionCode = 0;
+
+    uint8_t seconds = 55;
+    uint8_t minutes = 2;
+    uint8_t hours = 8;
+    uint8_t day = 9;
+    uint8_t month = 7;
+    uint16_t year = 2020;
+
+    uint8_t retSeconds = 0;
+    uint8_t retMinutes = 0;
+    uint8_t retHours = 0;
+    uint8_t retDay = 0;
+    uint8_t retMonth = 0;
+    uint16_t retYear = 0;
+
+    memcpy(response.payload + sizeof(completionCode), &seconds,
+           sizeof(seconds));
+    memcpy(response.payload + sizeof(completionCode) + sizeof(seconds),
+           &minutes, sizeof(minutes));
+    memcpy(response.payload + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes),
+           &hours, sizeof(hours));
+    memcpy(response.payload + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes) + sizeof(hours),
+           &day, sizeof(day));
+    memcpy(response.payload + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes) + sizeof(hours) + sizeof(day),
+           &month, sizeof(month));
+    memcpy(response.payload + sizeof(completionCode) + sizeof(seconds) +
+               sizeof(minutes) + sizeof(hours) + sizeof(day) + sizeof(month),
+           &year, sizeof(year));
+
+    auto rc = decode_get_date_time_resp(&response, &completionCode, &retSeconds,
+                                        &retMinutes, &retHours, &retDay,
+                                        &retMonth, &retYear);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(seconds, retSeconds);
+    ASSERT_EQ(minutes, retMinutes);
+    ASSERT_EQ(hours, retHours);
+    ASSERT_EQ(day, retDay);
+    ASSERT_EQ(month, retMonth);
+    ASSERT_EQ(year, retYear);
+}
diff --git a/test/libpldmresponder_bios_test.cpp b/test/libpldmresponder_bios_test.cpp
new file mode 100644
index 0000000..bcd3e5c
--- /dev/null
+++ b/test/libpldmresponder_bios_test.cpp
@@ -0,0 +1,46 @@
+
+#include "libpldmresponder/bios.hpp"
+
+#include <string.h>
+
+#include <array>
+#include <ctime>
+
+#include "libpldm/base.h"
+#include "libpldm/bios.h"
+
+#include <gtest/gtest.h>
+
+using namespace pldm::responder;
+using namespace pldm::responder::utils;
+
+TEST(epochToBCDTime, testTime)
+{
+    struct tm time
+    {
+    };
+    time.tm_year = 119;
+    time.tm_mon = 3;
+    time.tm_mday = 13;
+    time.tm_hour = 5;
+    time.tm_min = 18;
+    time.tm_sec = 13;
+    time.tm_isdst = -1;
+
+    time_t epochTime = mktime(&time);
+    uint8_t seconds = 0;
+    uint8_t minutes = 0;
+    uint8_t hours = 0;
+    uint8_t day = 0;
+    uint8_t month = 0;
+    uint16_t year = 0;
+
+    epochToBCDTime(epochTime, seconds, minutes, hours, day, month, year);
+
+    ASSERT_EQ(0x13, seconds);
+    ASSERT_EQ(0x18, minutes);
+    ASSERT_EQ(0x5, hours);
+    ASSERT_EQ(0x13, day);
+    ASSERT_EQ(0x4, month);
+    ASSERT_EQ(0x2019, year);
+}