Add support to read binary PMBus data
PMBus::readBinary() can read a sysfs file that
contains binary data and returns a vector of bytes
representing that data.
Change-Id: I3c729f502e155b007b9ab22a4eeefec437f150e1
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/pmbus.cpp b/pmbus.cpp
index f000c75..76ab39c 100644
--- a/pmbus.cpp
+++ b/pmbus.cpp
@@ -31,6 +31,17 @@
using namespace sdbusplus::xyz::openbmc_project::Common::Device::Error;
namespace fs = std::experimental::filesystem;
+/**
+ * @brief Helper to close a file handle
+ */
+struct FileCloser
+{
+ void operator()(FILE* fp) const
+ {
+ fclose(fp);
+ }
+};
+
std::string PMBus::insertPageNum(const std::string& templateName,
size_t page)
{
@@ -224,6 +235,52 @@
return data;
}
+std::vector<uint8_t> PMBus::readBinary(const std::string& name,
+ Type type,
+ size_t length)
+{
+ auto path = getPath(type) / name;
+
+ //Use C style IO because it's easier to handle telling the difference
+ //between hitting EOF or getting an actual error.
+ std::unique_ptr<FILE, FileCloser> file{fopen(path.c_str(), "rb")};
+
+ if (file)
+ {
+ std::vector<uint8_t> data(length, 0);
+
+ auto bytes = fread(data.data(),
+ sizeof(decltype(data[0])),
+ length,
+ file.get());
+
+ if (bytes != length)
+ {
+ //If hit EOF, just return the amount of data that was read.
+ if (feof(file.get()))
+ {
+ data.erase(data.begin() + bytes, data.end());
+ }
+ else if (ferror(file.get()))
+ {
+ auto rc = errno;
+ log<level::ERR>("Failed to read sysfs file",
+ entry("FILENAME=%s", path.c_str()));
+
+ using metadata = xyz::openbmc_project::Common::
+ Device::ReadFailure;
+
+ elog<ReadFailure>(metadata::CALLOUT_ERRNO(rc),
+ metadata::CALLOUT_DEVICE_PATH(
+ fs::canonical(basePath).c_str()));
+ }
+ }
+ return data;
+ }
+
+ return std::vector<uint8_t>{};
+}
+
void PMBus::write(const std::string& name, int value, Type type)
{
std::ofstream file;
diff --git a/pmbus.hpp b/pmbus.hpp
index cad77bf..55e3ff6 100644
--- a/pmbus.hpp
+++ b/pmbus.hpp
@@ -209,6 +209,19 @@
std::string readString(const std::string& name, Type type);
/**
+ * Read data from a binary file in sysfs.
+ *
+ * @param[in] name - path concatenated to basePath to read
+ * @param[in] type - Path type
+ * @param[in] length - length of data to read, in bytes
+ *
+ * @return vector<uint8_t> - The data read from the file.
+ */
+ std::vector<uint8_t> readBinary(const std::string& name,
+ Type type,
+ size_t length);
+
+ /**
* Writes an integer value to the file, therefore doing
* a PMBus write.
*