sensorhandler: Add functionality to use m, b, b_exp from config.yaml

Change-Id: I1b5b8a5e0e5abd74eadde494728f363cf1ca4ec6
Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/scripts/writesensor.mako.cpp b/scripts/writesensor.mako.cpp
index fbfe6a9..cb3be09 100644
--- a/scripts/writesensor.mako.cpp
+++ b/scripts/writesensor.mako.cpp
@@ -16,8 +16,12 @@
        path = sensor["path"]
        sensorType = sensor["sensorType"]
        readingType = sensor["sensorReadingType"]
+       multiplier = sensor.get("multiplierM", 1)
+       offset = sensor.get("offsetB", 0)
+       exp = sensor.get("bExp", 0)
 %>
-        ${sensorType},"${path}",${readingType},{
+        ${sensorType},"${path}",${readingType},${multiplier},${offset},${exp},
+        ${offset * pow(10,exp)},{
     % for interface,properties in interfaces.iteritems():
             {"${interface}",{
             % for dbus_property,property_value in properties.iteritems():
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index cbf6b65..25d6861 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -557,7 +557,7 @@
 
     *data_len=0;
 
-    int64_t raw_value, scale;
+    int64_t raw_value;
     ipmi::sensor::Info sensor;
 
     switch(type) {
@@ -593,6 +593,14 @@
         case IPMI_SENSOR_CURRENT:
         case IPMI_SENSOR_FAN:
             // Get reading for /xyz/openbmc_project/Sensor/Value.interface
+            if(sensors.find(reqptr->sennum) == sensors.end())
+            {
+                fprintf(stderr, "Failed to find config entry for Sensor 0x%02x\n",
+                        reqptr->sennum);
+                return IPMI_CC_SENSOR_INVALID;
+            }
+
+            sensor = sensors.at(reqptr->sennum);
 
             // Get value
             r = sd_bus_get_property_trivial(bus,
@@ -613,26 +621,13 @@
                 break;
             }
 
-            // Get scale
-            r = sd_bus_get_property_trivial(bus,
-                                            a.bus,
-                                            a.path,
-                                            a.interface,
-                                            "Scale",
-                                            NULL,
-                                            'x',
-                                            &scale);
-            if (r < 0) {
-                fprintf(stderr,
-                        "Failed to call sd_bus_get_property:%d,  %s (scale)\n",
-                        r,
-                        strerror(-r));
-                fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
-                        a.bus, a.path, a.interface);
-                break;
-            }
+            // Prevent div0
+            if (sensor.coefficientM == 0) {
+                sensor.coefficientM = 1;
+            };
 
-            resp->value = raw_value * pow(10,scale);
+            resp->value = static_cast<uint8_t>(
+                    (raw_value - sensor.scaledOffset) / sensor.coefficientM);
             resp->operation = 1<<6; // scanning enabled
             resp->indication[0] = 0; // not a threshold sensor. ignore
             resp->indication[1] = 0;
@@ -771,9 +766,25 @@
         free(raw_cstr);
 
         /* Modifiers to reading info */
-        get_sdr::body::set_b(0, body);
-        get_sdr::body::set_m(1, body);
-        body->r_b_exponents = 0;
+        // Get scale
+        int64_t scale;
+        if (0 > sd_bus_get_property_trivial(bus,
+                                        iface.bus,
+                                        iface.path,
+                                        iface.interface,
+                                        "Scale",
+                                        NULL,
+                                        'x',
+                                        &scale)) {
+            fprintf(stderr, "Expected to find Scale interface in bus %s, path %s, but it was missing.\n",
+                    iface.bus, iface.path);
+            return IPMI_CC_SENSOR_INVALID;
+        }
+
+        get_sdr::body::set_b(info->coefficientB, body);
+        get_sdr::body::set_m(info->coefficientM, body);
+        get_sdr::body::set_b_exp(info->exponentB, body);
+        get_sdr::body::set_r_exp(scale, body);
 
         /* ID string */
         std::string id_string = info->sensorPath.substr(
diff --git a/sensorhandler.h b/sensorhandler.h
index 2b1f527..3022296 100644
--- a/sensorhandler.h
+++ b/sensorhandler.h
@@ -258,7 +258,7 @@
     uint16_t reserved;
     uint8_t oem_reserved;
     uint8_t id_string_info;
-    char id_string[16];
+    char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
 } __attribute__((packed));
 
 namespace body
diff --git a/types.hpp b/types.hpp
index 4ad3306..37066f5 100644
--- a/types.hpp
+++ b/types.hpp
@@ -32,12 +32,20 @@
 using InstancePath = std::string;
 using Type = uint8_t;
 using ReadingType = uint8_t;
+using Multiplier = uint16_t;
+using OffsetB = uint16_t;
+using Exponent = uint8_t;
+using ScaledOffset = int64_t;
 
 struct Info
 {
    Type sensorType;
    InstancePath sensorPath;
    ReadingType sensorReadingType;
+   Multiplier coefficientM;
+   OffsetB coefficientB;
+   Exponent exponentB;
+   ScaledOffset scaledOffset;
    DbusInterfaceMap sensorInterfaces;
 };