Add hwmon support to PMBus class

Add support to allow the class to handle accessing
hwmon files even though the device path passed to
the constructor wasn't a hwmon path.

This is useful because the users of this class have
to access files in both locations.

For example:
  PMBus p(basePath);

  p.write("myfile", 1, Type::Base)
    -> writes to basePath/myfile

  p.write("myfile", 1, Type::Hwmon)
    -> writes to basePath/hwmon/hwmonN/myfile
       where hwmonN is the hwmon dir for the device

Change-Id: Ic66835dace2a9958310c9f4ee8cbcaae3669dd0f
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/pmbus.cpp b/pmbus.cpp
index 85e7c43..bd9e697 100644
--- a/pmbus.cpp
+++ b/pmbus.cpp
@@ -48,18 +48,25 @@
     return name;
 }
 
-bool PMBus::readBitInPage(const std::string& name, size_t page)
+bool PMBus::readBitInPage(const std::string& name,
+                          size_t page,
+                          Type type)
 {
     auto pagedBit = insertPageNum(name, page);
-    return readBit(pagedBit);
+    return readBit(pagedBit, type);
 }
 
-bool PMBus::readBit(const std::string& name)
+bool PMBus::readBit(const std::string& name, Type type)
 {
     unsigned long int value = 0;
     std::ifstream file;
     fs::path path{basePath};
 
+    if (type == Type::Hwmon)
+    {
+        path /= hwmonRelPath;
+    }
+
     path /= name;
 
     file.exceptions(std::ifstream::failbit |
@@ -103,11 +110,16 @@
     return value != 0;
 }
 
-void PMBus::write(const std::string& name, int value)
+void PMBus::write(const std::string& name, int value, Type type)
 {
     std::ofstream file;
     fs::path path{basePath};
 
+    if (type == Type::Hwmon)
+    {
+        path /= hwmonRelPath;
+    }
+
     path /= name;
 
     file.exceptions(std::ofstream::failbit |
@@ -134,5 +146,34 @@
     }
 }
 
+void PMBus::findHwmonRelativePath()
+{
+    fs::path path{basePath};
+    path /= "hwmon";
+
+    //look for <basePath>/hwmon/hwmonN/
+    for (auto& f : fs::directory_iterator(path))
+    {
+        if ((f.path().filename().string().find("hwmon") !=
+            std::string::npos) &&
+            (fs::is_directory(f.path())))
+        {
+            hwmonRelPath = "hwmon";
+            hwmonRelPath /= f.path().filename();
+            break;
+        }
+    }
+
+    //Don't really want to crash here, just log it
+    //and let accesses fail later
+    if (hwmonRelPath.empty())
+    {
+        log<level::ERR>("Unable to find hwmon directory "
+                        "in device base path",
+                        entry("DEVICE_PATH=%s", basePath.c_str()));
+    }
+
+}
+
 }
 }