nvmesensor: Use slave address from configuration json

Replace hardcoded slave address with address from the configuration
This patch is for non-compliant nvme devices (e.g.
configurations/nvme_p4000.json).
Tested: Manually by verifying the slave address in Entity Manager
configuration is used by the nvmesensor binary

Change-Id: I56b8187578c22a9be98ccd2c50a7b9838a087e52
Signed-off-by: Nnamdi Ajah <nnamdi@cloudflare.com>
diff --git a/src/NVMeBasicContext.cpp b/src/NVMeBasicContext.cpp
index 0bc2252..de18b42 100644
--- a/src/NVMeBasicContext.cpp
+++ b/src/NVMeBasicContext.cpp
@@ -263,7 +263,7 @@
         return;
     }
 
-    auto command = encodeBasicQuery(sensor->bus, 0x6a, 0x00);
+    auto command = encodeBasicQuery(sensor->bus, sensor->address, 0x00);
 
     /* Issue the request */
     boost::asio::async_write(
diff --git a/src/NVMeSensor.cpp b/src/NVMeSensor.cpp
index e11fae7..d265a02 100644
--- a/src/NVMeSensor.cpp
+++ b/src/NVMeSensor.cpp
@@ -27,11 +27,11 @@
                        const std::string& sensorName,
                        std::vector<thresholds::Threshold>&& thresholdsIn,
                        const std::string& sensorConfiguration,
-                       const int busNumber) :
+                       const int busNumber, const uint8_t slaveAddr) :
     Sensor(escapeName(sensorName), std::move(thresholdsIn), sensorConfiguration,
            NVMeSensor::sensorType, false, false, maxReading, minReading, conn,
            PowerState::on),
-    bus(busNumber), objServer(objectServer)
+    bus(busNumber), address(slaveAddr), objServer(objectServer)
 {
     if (bus < 0)
     {
diff --git a/src/NVMeSensor.hpp b/src/NVMeSensor.hpp
index dfed215..5d89d6a 100644
--- a/src/NVMeSensor.hpp
+++ b/src/NVMeSensor.hpp
@@ -13,7 +13,8 @@
                std::shared_ptr<sdbusplus::asio::connection>& conn,
                const std::string& sensorName,
                std::vector<thresholds::Threshold>&& thresholds,
-               const std::string& sensorConfiguration, int busNumber);
+               const std::string& sensorConfiguration, int busNumber,
+               uint8_t slaveAddr);
     ~NVMeSensor() override;
 
     NVMeSensor& operator=(const NVMeSensor& other) = delete;
@@ -21,6 +22,7 @@
     bool sample();
 
     int bus;
+    uint8_t address;
 
   private:
     const unsigned int scanDelayTicks = 5 * 60;
diff --git a/src/NVMeSensorMain.cpp b/src/NVMeSensorMain.cpp
index ef1abbe..9cd453e 100644
--- a/src/NVMeSensorMain.cpp
+++ b/src/NVMeSensorMain.cpp
@@ -23,6 +23,8 @@
 #include <optional>
 #include <regex>
 
+static constexpr uint8_t nvmeMiDefaultSlaveAddr = 0x6A;
+
 static NVMEMap nvmeDeviceMap;
 
 NVMEMap& getNVMEMap()
@@ -44,6 +46,21 @@
     return std::visit(VariantToIntVisitor(), findBus->second);
 }
 
+static uint8_t extractSlaveAddr(const std::string& path,
+                                const SensorBaseConfigMap& properties)
+{
+    auto findSlaveAddr = properties.find("Address");
+    if (findSlaveAddr == properties.end())
+    {
+        std::cerr << "could not determine slave address for " << path << "\n"
+                  << "using default as specified in nvme-mi"
+                  << "\n";
+        return nvmeMiDefaultSlaveAddr;
+    }
+
+    return std::visit(VariantToUnsignedIntVisitor(), findSlaveAddr->second);
+}
+
 static std::optional<std::string>
     extractSensorName(const std::string& path,
                       const SensorBaseConfigMap& properties)
@@ -138,6 +155,7 @@
             extractBusNumber(interfacePath, sensorConfig);
         std::optional<std::string> sensorName =
             extractSensorName(interfacePath, sensorConfig);
+        uint8_t slaveAddr = extractSlaveAddr(interfacePath, sensorConfig);
         std::optional<int> rootBus = deriveRootBus(busNumber);
 
         if (!(busNumber && sensorName && rootBus))
@@ -163,7 +181,8 @@
             std::shared_ptr<NVMeSensor> sensorPtr =
                 std::make_shared<NVMeSensor>(
                     objectServer, io, dbusConnection, *sensorName,
-                    std::move(sensorThresholds), interfacePath, *busNumber);
+                    std::move(sensorThresholds), interfacePath, *busNumber,
+                    slaveAddr);
 
             context->addSensor(sensorPtr);
         }