sensor: Add function to map dbus info to assertion status

Change-Id: I30aae9abd7905ae3299856d798d41e10859fed7f
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp
index b9ef5e2..231822b 100644
--- a/sensordatahandler.cpp
+++ b/sensordatahandler.cpp
@@ -1,9 +1,12 @@
 #include <bitset>
+#include <experimental/filesystem>
 #include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/log.hpp>
 #include "xyz/openbmc_project/Common/error.hpp"
 #include "types.hpp"
+#include "sensorhandler.h"
 #include "sensordatahandler.hpp"
+#include "utils.hpp"
 
 namespace ipmi
 {
@@ -104,6 +107,55 @@
     return IPMI_CC_OK;
 }
 
+namespace get
+{
+
+GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
+                                     const InstancePath& path,
+                                     const DbusInterface& interface)
+{
+    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+    GetSensorResponse response {};
+    auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
+
+    auto service = ipmi::getService(bus, interface, path);
+
+    const auto& interfaceList = sensorInfo.propertyInterfaces;
+
+    for (const auto& interface : interfaceList)
+    {
+        for (const auto& property : interface.second)
+        {
+            auto propValue = ipmi::getDbusProperty(bus,
+                                                   service,
+                                                   path,
+                                                   interface.first,
+                                                   property.first);
+
+            for (const auto& value : property.second)
+            {
+                if (propValue == value.second.assert)
+                {
+                    setOffset(value.first, responseData);
+                    break;
+                }
+
+            }
+        }
+    }
+
+    return response;
+}
+
+GetSensorResponse assertion(const Info& sensorInfo)
+{
+    return mapDbusToAssertion(sensorInfo,
+                              sensorInfo.sensorPath,
+                              sensorInfo.sensorInterface);
+}
+
+} //namespace get
+
 namespace set
 {
 
@@ -252,6 +304,30 @@
     msg.append(std::move(objects));
     return updateToDbus(msg);
 }
+
 }//namespace notify
+
+namespace inventory
+{
+
+namespace get
+{
+
+GetSensorResponse assertion(const Info& sensorInfo)
+{
+    namespace fs = std::experimental::filesystem;
+
+    fs::path path{ipmi::sensor::inventoryRoot};
+    path += sensorInfo.sensorPath;
+
+    return ipmi::sensor::get::mapDbusToAssertion(
+            sensorInfo,
+            path.string(),
+            sensorInfo.propertyInterfaces.begin()->first);
+}
+
+} //namespace get
+
+} // namespace inventory
 }//namespace sensor
 }//namespace ipmi
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
index ca82666..3a66f48 100644
--- a/sensordatahandler.hpp
+++ b/sensordatahandler.hpp
@@ -44,6 +44,35 @@
  */
 ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
 
+namespace get
+{
+
+/**
+ *  @brief Helper function to map the dbus info to sensor's assertion status
+ *         for the get sensor reading command.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *  @param[in] path - Dbus object path.
+ *  @param[in] interface - Dbus interface.
+ *
+ *  @return Response for get sensor reading command.
+ */
+GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
+                                     const InstancePath& path,
+                                     const DbusInterface& interface);
+
+/**
+ *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
+ *         reading command response.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return Response for get sensor reading command.
+ */
+GetSensorResponse assertion(const Info& sensorInfo);
+
+} //namespace get
+
 namespace set
 {
 
@@ -201,5 +230,25 @@
                      const Info& sensorInfo);
 
 }//namespace notify
+
+namespace inventory
+{
+
+namespace get
+{
+
+/**
+ *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
+ *         reading command response.
+ *
+ *  @param[in] sensorInfo - Dbus info related to sensor.
+ *
+ *  @return Response for get sensor reading command.
+ */
+GetSensorResponse assertion(const Info& sensorInfo);
+
+} // namespace get
+
+} // namespace inventory
 }//namespace sensor
 }//namespace ipmi
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index b6e7890..4933afb 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -421,8 +421,8 @@
 
 ipmi_ret_t setSensorReading(void *request)
 {
-    SetSensorReadingReq cmdData =
-            *(static_cast<SetSensorReadingReq *>(request));
+    ipmi::sensor::SetSensorReadingReq cmdData =
+            *(static_cast<ipmi::sensor::SetSensorReadingReq *>(request));
 
     // Check if the Sensor Number is present
     const auto iter = sensors.find(cmdData.number);
diff --git a/sensorhandler.h b/sensorhandler.h
index 0b4c4e5..576c803 100644
--- a/sensorhandler.h
+++ b/sensorhandler.h
@@ -2,6 +2,7 @@
 #define __HOST_IPMI_SEN_HANDLER_H__
 
 #include <stdint.h>
+#include "types.hpp"
 
 // IPMI commands for net functions.
 enum ipmi_netfn_sen_cmds
@@ -39,25 +40,6 @@
 int find_openbmc_path(uint8_t , dbus_interface_t *);
 
 /**
- * @struct SetSensorReadingReq
- *
- * IPMI Request data for Set Sensor Reading and Event Status Command
- */
-struct SetSensorReadingReq
-{
-    uint8_t number;
-    uint8_t operation;
-    uint8_t reading;
-    uint8_t assertOffset0_7;
-    uint8_t assertOffset8_14;
-    uint8_t deassertOffset0_7;
-    uint8_t deassertOffset8_14;
-    uint8_t eventData1;
-    uint8_t eventData2;
-    uint8_t eventData3;
-} __attribute__((packed));
-
-/**
  * Get SDR Info
  */
 
@@ -489,4 +471,35 @@
 } __attribute__((packed));
 
 } // get_sdr
+
+namespace ipmi
+{
+
+namespace sensor
+{
+
+/**
+ * @brief Map offset to the corresponding bit in the assertion byte.
+ *
+ * The discrete sensors support upto 14 states. 0-7 offsets are stored in one
+ * byte and offsets 8-14 in the second byte.
+ *
+ * @param[in] offset - offset number.
+ * @param[in/out] resp - get sensor reading response.
+ */
+inline void setOffset(uint8_t offset, ipmi::sensor::GetReadingResponse* resp)
+{
+    if (offset > 7)
+    {
+        resp->assertOffset8_14 |= 1 << (offset - 8);
+    }
+    else
+    {
+        resp->assertOffset0_7 |= 1 << offset;
+    }
+}
+
+} // namespace sensor
+
+} // namespace ipmi
 #endif
diff --git a/types.hpp b/types.hpp
index ae88faa..330a8a6 100644
--- a/types.hpp
+++ b/types.hpp
@@ -6,7 +6,6 @@
 #include <string>
 
 #include <sdbusplus/server.hpp>
-#include "sensorhandler.h"
 
 namespace ipmi
 {
@@ -39,6 +38,42 @@
    Value deassert;
 };
 
+/**
+ * @struct SetSensorReadingReq
+ *
+ * IPMI Request data for Set Sensor Reading and Event Status Command
+ */
+struct SetSensorReadingReq
+{
+    uint8_t number;
+    uint8_t operation;
+    uint8_t reading;
+    uint8_t assertOffset0_7;
+    uint8_t assertOffset8_14;
+    uint8_t deassertOffset0_7;
+    uint8_t deassertOffset8_14;
+    uint8_t eventData1;
+    uint8_t eventData2;
+    uint8_t eventData3;
+} __attribute__((packed));
+
+/**
+ * @struct GetReadingResponse
+ *
+ * IPMI response data for Get Sensor Reading command.
+ */
+struct GetReadingResponse
+{
+    uint8_t reading;            //!< Sensor reading.
+    uint8_t operation;          //!< Sensor scanning status / reading state.
+    uint8_t assertOffset0_7;    //!< Discrete assertion states(0-7).
+    uint8_t assertOffset8_14;   //!< Discrete assertion states(8-14).
+} __attribute__((packed));
+
+constexpr auto inventoryRoot = "/xyz/openbmc_project/inventory";
+
+using GetSensorResponse = std::array<uint8_t, sizeof(GetReadingResponse)>;
+
 using OffsetValueMap = std::map<Offset,Values>;
 
 using DbusPropertyMap = std::map<DbusProperty,OffsetValueMap>;