NVMeContext: Improve encapsulation of state

Consolidate NVMe MI MCTP message exchange and data parsing in the
NVMeContext implementation, and prevent NVMeSensorMain reaching into
internal details of NVMeContext when adding new sensors.

Previously message data parsing was intermixed with the MCTP message
handler implementation. Instead, make the MCTP message handler simply
dispatch the message buffer to the appropriate context instance.

Refactoring the code in this way makes it easier to later extract a base
class from the NVMeContext implementation.

Change-Id: I77bdfb703fd3da43186994d7b306076bd092afcf
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/src/NVMeContext.cpp b/src/NVMeContext.cpp
index c421d1f..36be841 100644
--- a/src/NVMeContext.cpp
+++ b/src/NVMeContext.cpp
@@ -107,6 +107,27 @@
 
 } // namespace nvmeMCTP
 
+static void rxMessage(uint8_t eid, void*, void* msg, size_t len)
+{
+    int inFd = mctp_smbus_get_in_fd(nvmeMCTP::smbus);
+    int rootBus = nvmeMCTP::getRootBus(inFd);
+
+    NVMEMap& nvmeMap = getNVMEMap();
+    auto findMap = nvmeMap.find(rootBus);
+    if (findMap == nvmeMap.end())
+    {
+        std::cerr << "Unable to lookup root bus " << rootBus << "\n";
+        return;
+    }
+
+    if (debug)
+    {
+        std::cout << "Eid from the received messaged: " << eid << "\n";
+    }
+
+    findMap->second->processResponse(msg, len);
+}
+
 static int verifyIntegrity(uint8_t* msg, size_t len)
 {
     uint32_t msgIntegrity = {0};
@@ -143,23 +164,11 @@
     return reading;
 }
 
-static void rxMessage(uint8_t eid, void*, void* msg, size_t len)
+void NVMeContext::processResponse(void* msg, size_t len)
 {
     struct nvme_mi_msg_response_header header
     {};
 
-    int inFd = mctp_smbus_get_in_fd(nvmeMCTP::smbus);
-    int rootBus = nvmeMCTP::getRootBus(inFd);
-
-    NVMEMap& nvmeMap = getNVMEMap();
-    auto findMap = nvmeMap.find(rootBus);
-    if (findMap == nvmeMap.end())
-    {
-        std::cerr << "Unable to lookup root bus " << rootBus << "\n";
-        return;
-    }
-    std::shared_ptr<NVMeContext>& self = findMap->second;
-
     if (msg == nullptr)
     {
         std::cerr << "Bad message received\n";
@@ -172,11 +181,6 @@
         return;
     }
 
-    if (debug)
-    {
-        std::cout << "Eid from the received messaged: " << eid << "\n";
-    }
-
     uint8_t* messageData = static_cast<uint8_t*>(msg);
 
     if ((*messageData & NVME_MI_MESSAGE_TYPE_MASK) != NVME_MI_MESSAGE_TYPE)
@@ -229,7 +233,7 @@
         return;
     }
 
-    std::shared_ptr<NVMeSensor> sensorInfo = self->sensors.front();
+    std::shared_ptr<NVMeSensor> sensorInfo = sensors.front();
     if (debug)
     {
         std::cout << "Temperature Reading: "
@@ -254,10 +258,10 @@
     }
 
     // move to back of scan queue
-    self->sensors.pop_front();
-    self->sensors.emplace_back(sensorInfo);
+    sensors.pop_front();
+    sensors.emplace_back(sensorInfo);
 
-    self->mctpResponseTimer.cancel();
+    mctpResponseTimer.cancel();
 }
 
 static int nvmeMessageTransmit(mctp& mctp, nvme_mi_msg_request& req)
@@ -310,26 +314,24 @@
     return mctp_message_tx(&mctp, 0, messageBuf.data(), msgSize);
 }
 
-static void readResponse(const std::shared_ptr<NVMeContext>& nvmeDevice)
+void NVMeContext::readResponse()
 {
-    nvmeDevice->nvmeSlaveSocket.async_wait(
+    nvmeSlaveSocket.async_wait(
         boost::asio::ip::tcp::socket::wait_error,
-        [nvmeDevice](const boost::system::error_code errorCode) {
+        [this](const boost::system::error_code errorCode) {
             if (errorCode)
             {
                 return;
             }
 
-            mctp_smbus_set_in_fd(nvmeMCTP::smbus,
-                                 nvmeMCTP::getInFd(nvmeDevice->rootBus));
+            mctp_smbus_set_in_fd(nvmeMCTP::smbus, nvmeMCTP::getInFd(rootBus));
 
             // through libmctp this will invoke rxMessage
             mctp_smbus_read(nvmeMCTP::smbus);
         });
 }
 
-static void
-    readAndProcessNVMeSensor(const std::shared_ptr<NVMeContext>& nvmeDevice)
+void NVMeContext::readAndProcessNVMeSensor()
 {
     struct nvme_mi_msg_request requestMsg = {};
     requestMsg.header.opcode = NVME_MI_OPCODE_HEALTH_STATUS_POLL;
@@ -338,19 +340,19 @@
 
     int mctpResponseTimeout = 1;
 
-    if (nvmeDevice->sensors.empty())
+    if (sensors.empty())
     {
         return;
     }
 
-    std::shared_ptr<NVMeSensor>& sensor = nvmeDevice->sensors.front();
+    std::shared_ptr<NVMeSensor>& sensor = sensors.front();
 
     // setup the timeout timer
-    nvmeDevice->mctpResponseTimer.expires_from_now(
+    mctpResponseTimer.expires_from_now(
         boost::posix_time::seconds(mctpResponseTimeout));
 
-    nvmeDevice->mctpResponseTimer.async_wait(
-        [sensor, nvmeDevice](const boost::system::error_code errorCode) {
+    mctpResponseTimer.async_wait(
+        [sensor, this](const boost::system::error_code errorCode) {
             if (errorCode)
             {
                 // timer cancelled successfully
@@ -360,18 +362,18 @@
             sensor->incrementError();
 
             // cycle it back
-            nvmeDevice->sensors.pop_front();
-            nvmeDevice->sensors.emplace_back(sensor);
+            sensors.pop_front();
+            sensors.emplace_back(sensor);
 
-            nvmeDevice->nvmeSlaveSocket.cancel();
+            nvmeSlaveSocket.cancel();
         });
 
-    readResponse(nvmeDevice);
+    readResponse();
 
     if (debug)
     {
         std::cout << "Sending message to read data from Drive on bus: "
-                  << sensor->bus << " , rootBus: " << nvmeDevice->rootBus
+                  << sensor->bus << " , rootBus: " << rootBus
                   << " device: " << sensor->name << "\n";
     }
 
@@ -407,7 +409,7 @@
             }
             else
             {
-                readAndProcessNVMeSensor(self);
+                self->readAndProcessNVMeSensor();
             }
 
             self->pollNVMeDevices();
@@ -422,6 +424,11 @@
     nvmeMCTP::closeInFd(rootBus);
 }
 
+void NVMeContext::addSensor(std::shared_ptr<NVMeSensor> sensor)
+{
+    sensors.emplace_back(sensor);
+}
+
 NVMeContext::~NVMeContext()
 {
     close();