nvmesensor: Support the NVMe MI basic management command

The NVMe MI basic management command is an optional extension to the
NVMe specification that allows management controllers to query drive
state without needing an MCTP stack[1].

[1] https://nvmexpress.org/wp-content/uploads/NVMe_Management_-_Technical_Note_on_Basic_Management_Command.pdf

Given the current lack of support for the SMBus MCTP binding in upstream
OpenBMC, provide an NVMe MI basic management command implementation that
allows nvmesensor to function without diving into a maze of out-of-tree
patches.

As we're doing this in userspace we exploit Linux's I2C chardev
interface for talking to the drives. However, the interface is driven by
ioctl()s, which interacts poorly with the event-driven ASIO design.

Click the lego together by using an IO thread to transform ioctl()s into
read() and write() operations that we can handle asynchronously.

Change-Id: I08cca4991a2ddea23fe8fcc1cf5365d4baded11c
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/include/NVMeBasicContext.hpp b/include/NVMeBasicContext.hpp
new file mode 100644
index 0000000..579030e
--- /dev/null
+++ b/include/NVMeBasicContext.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "NVMeContext.hpp"
+
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/posix/stream_descriptor.hpp>
+
+class NVMeBasicContext : public NVMeContext
+{
+  public:
+    NVMeBasicContext(boost::asio::io_service& io, int rootBus);
+    virtual ~NVMeBasicContext() = default;
+    virtual void pollNVMeDevices() override;
+    virtual void readAndProcessNVMeSensor() override;
+    virtual void processResponse(void* msg, size_t len) override;
+
+  private:
+    NVMeBasicContext(boost::asio::io_service& io, int rootBus, int cmdOut,
+                     int streamIn, int streamOut, int cmdIn);
+    boost::asio::io_service& io;
+    boost::asio::posix::stream_descriptor reqStream;
+    boost::asio::posix::stream_descriptor respStream;
+};