Add the BIOSPostCode events into the BMCWeb EventService

- Add BIOSPostCode events to the bmcweb redfish event log, so that
  users can collect BIOSPOSTCode events through redfish EventService.
  Refer to:
  https://github.com/openbmc/docs/blob/master/architecture/redfish-logging-in-bmcweb.md
- Add CMake option to trun on/off the log of post code.
  The default setting is off.

Tested:
  - Tested build OK.
  - Check /var/log/redfish OK.
    1970-01-01T00:05:06.042545+00:00 OpenBMC.0.1.BIOSPOSTCode,1,267.5030,0x15
    1970-01-01T00:05:06.182087+00:00 OpenBMC.0.1.BIOSPOSTCode,1,267.5813,0x7f
    1970-01-01T00:05:06.276475+00:00 OpenBMC.0.1.BIOSPOSTCode,1,267.7245,0x00

Signed-off-by: Alan Kuo <Alan_Kuo@quantatw.com>
Change-Id: Ieff2acd81ee6fbd74ad8005680499e6753860037
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2cce209..7c68a66 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,10 @@
 cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
 project(post-code-manager CXX)
+option (
+    ENABLE_BIOS_POST_CODE_LOG
+    "Enable Bios Post Code Logging"
+    OFF
+)
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
@@ -43,4 +48,7 @@
 target_link_libraries(${PROJECT_NAME} "${SDBUSPLUSPLUS_LIBRARIES} -lstdc++fs -lphosphor_dbus")
 
 install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
+target_compile_definitions (
+    ${PROJECT_NAME} PRIVATE $<$<BOOL:${ENABLE_BIOS_POST_CODE_LOG}>: -DENABLE_BIOS_POST_CODE_LOG>
+)
 install (FILES ${SERVICE_FILES} DESTINATION /lib/systemd/system/)
diff --git a/src/post_code.cpp b/src/post_code.cpp
index 88035c5..31c3e16 100644
--- a/src/post_code.cpp
+++ b/src/post_code.cpp
@@ -72,6 +72,7 @@
 
 void PostCode::savePostCodes(postcode_t code)
 {
+    uint64_t usTimeOffset = 0;
     // steady_clock is a monotonic clock that is guaranteed to never be adjusted
     auto postCodeTimeSteady = std::chrono::steady_clock::now();
     uint64_t tsUS = std::chrono::duration_cast<std::chrono::microseconds>(
@@ -87,15 +88,37 @@
     else
     {
         // calculating tsUS so it is monotonic within the same boot
-        tsUS = firstPostCodeUsSinceEpoch +
-               std::chrono::duration_cast<std::chrono::microseconds>(
-                   postCodeTimeSteady - firstPostCodeTimeSteady)
-                   .count();
+        usTimeOffset = std::chrono::duration_cast<std::chrono::microseconds>(
+                           postCodeTimeSteady - firstPostCodeTimeSteady)
+                           .count();
+        tsUS = usTimeOffset + firstPostCodeUsSinceEpoch;
     }
 
     postCodes.insert(std::make_pair(tsUS, code));
     serialize(fs::path(strPostCodeListPath));
 
+#ifdef ENABLE_BIOS_POST_CODE_LOG
+    std::ostringstream hexCode;
+    hexCode << "0x" << std::setfill('0') << std::setw(2) << std::hex
+            << std::get<0>(code);
+
+    std::ostringstream timeOffsetStr;
+    // Set Fixed-Point Notation
+    timeOffsetStr << std::fixed;
+    // Set precision to 4 digits
+    timeOffsetStr << std::setprecision(4);
+    // Add double to stream
+    timeOffsetStr << static_cast<double>(usTimeOffset) / 1000 / 1000;
+
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "BIOS POST Code",
+        phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
+                                 "OpenBMC.0.1.BIOSPOSTCode"),
+        phosphor::logging::entry(
+            "REDFISH_MESSAGE_ARGS=%d,%s,%s", currentBootCycleIndex,
+            timeOffsetStr.str().c_str(), hexCode.str().c_str()));
+#endif
+
     return;
 }