dcmi: implement get sensor info

This commit implements the plumbing around the 'Get Sensor
Info' command. It doesn't read the sensor information yet.
That code is coming up in a subsequent commit.

Refactor some of the get temperature readings code, in order to reuse
certain common aspects for this commit.

Change-Id: I0cb531b5b75e98cc9e76509f84f832be9997fee0
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/dcmihandler.hpp b/dcmihandler.hpp
index 4e95eba..09921a0 100644
--- a/dcmihandler.hpp
+++ b/dcmihandler.hpp
@@ -10,6 +10,9 @@
 namespace dcmi
 {
 
+using NumInstances = size_t;
+using Json = nlohmann::json;
+
 enum Commands
 {
     // Get capability bits
@@ -19,6 +22,7 @@
     SET_POWER_LIMIT = 0x04,
     APPLY_POWER_LIMIT = 0x05,
     GET_ASSET_TAG = 0x06,
+    GET_SENSOR_INFO = 0x07,
     SET_ASSET_TAG = 0x08,
     GET_MGMNT_CTRL_ID_STR = 0x09,
     SET_MGMNT_CTRL_ID_STR = 0x0A,
@@ -36,6 +40,9 @@
         "xyz.openbmc_project.Network.SystemConfiguration";
 static constexpr auto hostNameProp = "HostName";
 static constexpr auto temperatureSensorType = 0x01;
+static constexpr auto maxInstances = 255;
+static constexpr auto configFile =
+    "/usr/share/ipmi-providers/dcmi_sensors.json";
 
 namespace assettag
 {
@@ -50,10 +57,7 @@
 namespace temp_readings
 {
     static constexpr auto maxDataSets = 8;
-    static constexpr auto maxInstances = 255;
     static constexpr auto maxTemp = 127; // degrees C
-    static constexpr auto configFile =
-        "/usr/share/ipmi-providers/dcmi_temp_readings.json";
 
     /** @struct Response
      *
@@ -73,13 +77,28 @@
     } __attribute__((packed));
 
     using ResponseList = std::vector<Response>;
-    using NumInstances = size_t;
     using Value = uint8_t;
     using Sign = bool;
     using Temperature = std::tuple<Value, Sign>;
-    using Json = nlohmann::json;
 }
 
+namespace sensor_info
+{
+    static constexpr auto maxRecords = 8;
+
+    /** @struct Response
+     *
+     *  DCMI payload for Get Sensor Info response
+     */
+    struct Response
+    {
+        uint8_t recordIdLsb;       //!< SDR record id LS byte
+        uint8_t recordIdMsb;       //!< SDR record id MS byte
+    } __attribute__((packed));
+
+    using ResponseList = std::vector<Response>;
+} // namespace sensor_info
+
 static constexpr auto groupExtId = 0xDC;
 
 static constexpr auto assetTagMaxOffset = 62;
@@ -381,6 +400,13 @@
     uint8_t numDataSets;            //!< No. of sets of temperature data
 } __attribute__((packed));
 
+/** @brief Parse out JSON config file containing information
+ *         related to sensors.
+ *
+ *  @return A json object
+ */
+Json parseSensorConfig();
+
 namespace temp_readings
 {
     /** @brief Read temperature from a d-bus object, scale it as per dcmi
@@ -394,13 +420,6 @@
     Temperature readTemp(const std::string& dbusService,
                          const std::string& dbusPath);
 
-    /** @brief Parse out JSON config file containing information
-     *         related to temperature readings.
-     *
-     *  @return A json object
-     */
-    Json parseConfig();
-
     /** @brief Read temperatures and fill up DCMI response for the Get
      *         Temperature Readings command. This looks at a specific
      *         instance.
@@ -428,6 +447,39 @@
                                                    uint8_t instanceStart);
 }
 
+namespace sensor_info
+{
+    /** @brief Read sensor info and fill up DCMI response for the Get
+     *         Sensor Info command. This looks at a specific
+     *         instance.
+     *
+     *  @param[in] type - one of "inlet", "cpu", "baseboard"
+     *  @param[in] instance - A non-zero Entity instance number
+     *  @param[in] config - JSON config info about DCMI sensors
+     *
+     *  @return A tuple, containing a sensor info response and
+     *          number of instances.
+     */
+    std::tuple<Response, NumInstances> read(const std::string& type,
+                                            uint8_t instance,
+                                            const Json& config);
+
+    /** @brief Read sensor info and fill up DCMI response for the Get
+     *         Sensor Info command. This looks at a range of
+     *         instances.
+     *
+     *  @param[in] type - one of "inlet", "cpu", "baseboard"
+     *  @param[in] instanceStart - Entity instance start index
+     *  @param[in] config - JSON config info about DCMI sensors
+     *
+     *  @return A tuple, containing a list of sensor info responses and the
+     *          number of instances.
+     */
+    std::tuple<ResponseList, NumInstances> readAll(const std::string& type,
+                                                   uint8_t instanceStart,
+                                                   const Json& config);
+} // namespace sensor_info
+
 /** @brief Read power reading from power reading sensor object
  *
  *  @param[in] bus - dbus connection
@@ -469,6 +521,30 @@
     uint8_t powerReadingState;  //!< Power Reading State
 } __attribute__((packed));
 
+/** @struct GetSensorInfoRequest
+ *
+ *  DCMI payload for Get Sensor Info request
+ */
+struct GetSensorInfoRequest
+{
+    uint8_t groupID;             //!< Group extension identification.
+    uint8_t sensorType;          //!< Type of the sensor
+    uint8_t entityId;            //!< Entity ID
+    uint8_t entityInstance;      //!< Entity Instance (0 means all instances)
+    uint8_t instanceStart;       //!< Instance start (used if instance is 0)
+} __attribute__((packed));
+
+/** @struct GetSensorInfoResponseHdr
+ *
+ *  DCMI header for Get Sensor Info response
+ */
+struct GetSensorInfoResponseHdr
+{
+    uint8_t groupID;                //!< Group extension identification.
+    uint8_t numInstances;           //!< No. of instances for requested id
+    uint8_t numRecords;             //!< No. of record ids in the response
+} __attribute__((packed));
+
 } // namespace dcmi
 
 #endif