Open device and populate file descriptor

Change-Id: I8159f71ff3dd087f10cdf3b013e1acb60d4758fb
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/file.hpp b/file.hpp
new file mode 100644
index 0000000..4d0a83c
--- /dev/null
+++ b/file.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <unistd.h>
+namespace open_power
+{
+namespace occ
+{
+namespace pass_through
+{
+/** @class FileDescriptor
+ *  @brief Responsible for handling file descriptor
+ */
+class FileDescriptor
+{
+    private:
+        /** @brief File descriptor for the gpio input device */
+        int fd = -1;
+
+    public:
+        FileDescriptor() = delete;
+        FileDescriptor(const FileDescriptor&) = delete;
+        FileDescriptor& operator=(const FileDescriptor&) = delete;
+        FileDescriptor(FileDescriptor&&) = delete;
+        FileDescriptor& operator=(FileDescriptor&&) = delete;
+
+        /** @brief Saves File descriptor and uses it to do file operation
+         *
+         *  @param[in] fd - File descriptor
+         */
+        FileDescriptor(int fd) : fd(fd)
+        {
+            // Nothing
+        }
+
+        ~FileDescriptor()
+        {
+            if (fd >=0)
+            {
+                close(fd);
+            }
+        }
+
+        int operator()()
+        {
+            return fd;
+        }
+};
+
+} // namespace pass_through
+} // namespace occ
+} // namespace open-power
diff --git a/occ_pass_through.cpp b/occ_pass_through.cpp
index 05864c1..88a0d29 100644
--- a/occ_pass_through.cpp
+++ b/occ_pass_through.cpp
@@ -1,5 +1,6 @@
 #include <memory>
 #include <algorithm>
+#include <fcntl.h>
 #include <phosphor-logging/log.hpp>
 #include "occ_pass_through.hpp"
 #include "occ_finder.hpp"
@@ -38,32 +39,29 @@
     sdbusplus::bus::bus& bus,
     const char* path) :
     Iface(bus, path),
-    path(path)
+    path(path),
+    fd(openDevice())
 {
+    // Nothing to do.
+}
+
+int PassThrough::openDevice()
+{
+    // Device instance number starts from 1.
     devicePath.append(std::to_string((this->path.back() - '0') + 1));
+
+    int fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK);
+    if (fd < 0)
+    {
+        // This is for completion. This is getting replaced by elog
+        // in the next commit
+        throw std::runtime_error("Error opening " + devicePath);
+    }
+    return fd;
 }
 
 std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
 {
-    std::string msg = "Pass through to OCC ";
-    msg += path;
-
-    std::string cmd;
-    std::for_each(command.cbegin(), command.cend(),
-                  [&cmd](const auto& c)
-                  {
-                      cmd += std::to_string(c);
-                      cmd += ',';
-                  });
-    if (!cmd.empty())
-    {
-        // Remove trailing ','
-        cmd.pop_back();
-    }
-
-    using namespace phosphor::logging;
-    log<level::INFO>(msg.c_str(), entry("COMMAND=%s", cmd.c_str()));
-
     return {};
 }
 
diff --git a/occ_pass_through.hpp b/occ_pass_through.hpp
index da8c617..673b68e 100644
--- a/occ_pass_through.hpp
+++ b/occ_pass_through.hpp
@@ -2,10 +2,12 @@
 
 #include <string>
 #include <vector>
+#include <unistd.h>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/server/object.hpp>
 #include "org/open_power/OCC/PassThrough/server.hpp"
 #include "config.h"
+#include "file.hpp"
 
 namespace open_power
 {
@@ -39,11 +41,11 @@
 {
     public:
         PassThrough() = delete;
+        ~PassThrough() = default;
         PassThrough(const PassThrough&) = delete;
         PassThrough& operator=(const PassThrough&) = delete;
         PassThrough(PassThrough&&) = default;
         PassThrough& operator=(PassThrough&&) = default;
-        ~PassThrough() = default;
 
         /** @brief Ctor to put pass-through d-bus object on the bus
          *  @param[in] bus - Bus to attach to
@@ -65,12 +67,18 @@
 
         /** @brief OCC device path
          *  For now, here is the hard-coded mapping until
-         *  the udev rule is in
+         *  the udev rule is in.
          *  occ0 --> /dev/occfifo1
          *  occ1 --> /dev/occfifo2
          *  ...
          */
         std::string devicePath = "/dev/occfifo";
+
+        /** @brief File descriptor manager */
+        FileDescriptor fd;
+
+        /** Opens devicePath and returns file descritor */
+        int openDevice();
 };
 
 } // namespace pass_through