summaryrefslogtreecommitdiffstats
path: root/cooling-type
diff options
context:
space:
mode:
Diffstat (limited to 'cooling-type')
-rw-r--r--cooling-type/Makefile.am8
-rw-r--r--cooling-type/argument.cpp22
-rw-r--r--cooling-type/cooling_type.cpp54
-rw-r--r--cooling-type/cooling_type.hpp27
-rw-r--r--cooling-type/main.cpp56
5 files changed, 107 insertions, 60 deletions
diff --git a/cooling-type/Makefile.am b/cooling-type/Makefile.am
index 8b41812..b18b2d6 100644
--- a/cooling-type/Makefile.am
+++ b/cooling-type/Makefile.am
@@ -11,11 +11,13 @@ phosphor_cooling_type_SOURCES = \
phosphor_cooling_type_CXXFLAGS = \
$(SDBUSPLUS_CFLAGS) \
- $(PHOSPHOR_LOGGING_CFLAGS)
+ $(PHOSPHOR_LOGGING_CFLAGS) \
+ $(LIBEVDEV_CFLAGS)
phosphor_cooling_type_LDADD = \
- $(top_builddir)/libfan.la \
+ ${top_builddir}/libfan.la \
$(SDBUSPLUS_LIBS) \
- $(PHOSPHOR_LOGGING_LIBS)
+ $(PHOSPHOR_LOGGING_LIBS) \
+ $(LIBEVDEV_LIBS)
# vim: tabstop=8 noexpandtab
diff --git a/cooling-type/argument.cpp b/cooling-type/argument.cpp
index da1e5a3..f0a78c2 100644
--- a/cooling-type/argument.cpp
+++ b/cooling-type/argument.cpp
@@ -70,26 +70,34 @@ void ArgumentParser::usage(char** argv)
std::cerr << "Usage: " << argv[0] << " [options]\n";
std::cerr << "Options:\n";
std::cerr << " --help print this menu\n";
- std::cerr << " --air Indicate air cooled is set\n";
- std::cerr << " --water Indicate water cooled is set\n";
- std::cerr << " --gpio=<pin> GPIO pin to read\n";
+ std::cerr << " --air Force 'AirCooled' property to be set"
+ " to true.\n";
+ std::cerr << " --water Force 'WaterCooled' property to be "
+ "set to true.\n";
+ std::cerr << " --dev=<pin> Device to read for GPIO pin state to"
+ " determine 'WaterCooled' (true) and 'AirCooled' (false)\n";
+ std::cerr << " --event=<keycode> Keycode for pin to read\n";
std::cerr <<
- " --path=<objpath> Object path under inventory to have "
- "CoolingType updated\n";
+ " --path=<objpath> *Required* object path under inventory "
+ "to have CoolingType updated\n";
+ std::cerr << "\nThe --air / --water options may be given in addtion to "
+ "--gpio, in which case both their setting and the GPIO will take "
+ "effect.\n";
std::cerr << std::flush;
}
const option ArgumentParser::options[] =
{
{ "path", required_argument, NULL, 'p' },
- { "gpio", required_argument, NULL, 'g' },
+ { "dev", required_argument, NULL, 'd' },
+ { "event", required_argument, NULL, 'e' },
{ "air", no_argument, NULL, 'a' },
{ "water", no_argument, NULL, 'w' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0},
};
-const char* ArgumentParser::optionstr = "p:g:aw?h";
+const char* ArgumentParser::optionstr = "p:d:e:aw?h";
const std::string ArgumentParser::empty_string = "";
diff --git a/cooling-type/cooling_type.cpp b/cooling-type/cooling_type.cpp
index 1c36daf..eb4a449 100644
--- a/cooling-type/cooling_type.cpp
+++ b/cooling-type/cooling_type.cpp
@@ -1,7 +1,8 @@
-#include <unistd.h>
#include <fcntl.h>
+#include <unistd.h>
#include <sdbusplus/bus.hpp>
#include <phosphor-logging/log.hpp>
+#include <libevdev/libevdev.h>
#include "utility.hpp"
#include "cooling_type.hpp"
@@ -12,6 +13,23 @@ namespace cooling
namespace type
{
+std::unique_ptr<libevdev, FreeEvDev> evdevOpen(int fd)
+{
+ libevdev* gpioDev = nullptr;
+
+ auto rc = libevdev_new_from_fd(fd, &gpioDev);
+ if (!rc)
+ {
+ return decltype(evdevOpen(0))(gpioDev);
+ }
+
+ //TODO - Create error log for failure. openbmc/openbmc#1542
+ throw std::runtime_error("Failed to get libevdev from file descriptor"
+ " rc = " + std::to_string(rc));
+
+ return decltype(evdevOpen(0))(nullptr);
+}
+
void CoolingType::setAirCooled()
{
airCooled = true;
@@ -22,26 +40,33 @@ void CoolingType::setWaterCooled()
waterCooled = true;
}
-void CoolingType::setupGpio(const std::string& gpioPath)
+void CoolingType::readGpio(const std::string& gpioPath, unsigned int keycode)
{
using namespace phosphor::logging;
- gpioFd = open(gpioPath.c_str(), O_RDONLY);
- if (gpioFd.is_open())
+ gpioFd.open(gpioPath.c_str(), O_RDONLY);
+
+ auto gpioDev = evdevOpen(gpioFd());
+
+ auto value = static_cast<int>(0);
+ auto fetch_rc = libevdev_fetch_event_value(gpioDev.get(), EV_KEY,
+ keycode, &value);
+ if (0 == fetch_rc)
+ {
+ //TODO - Create error log for failure. openbmc/openbmc#1542
+ throw std::runtime_error(
+ "Device does not support event type=EV_KEY and code=" +
+ std::to_string(keycode));
+ }
+
+ // TODO openbmc/phosphor-fan-presence#6
+ if (value > 0)
{
- auto rc = 0;//libevdev_new_from_fd(gpiofd, &gpioDev);//FIXME
- if (rc < 0)
- {
- throw std::runtime_error("Failed to get libevdev from " +
- gpioPath + " rc = " +
- std::to_string(rc));
- }
-
- //TODO - more to go here?
+ setWaterCooled();
}
else
{
- throw std::runtime_error("Failed to open GPIO file device");
+ setAirCooled();
}
}
@@ -88,5 +113,4 @@ void CoolingType::updateInventory(const std::string& objpath)
}
}
}
-
// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
diff --git a/cooling-type/cooling_type.hpp b/cooling-type/cooling_type.hpp
index 8775a42..aa02bfa 100644
--- a/cooling-type/cooling_type.hpp
+++ b/cooling-type/cooling_type.hpp
@@ -1,5 +1,6 @@
#pragma once
#include "utility.hpp"
+#include <libevdev/libevdev.h>
namespace phosphor
{
@@ -11,6 +12,14 @@ namespace type
constexpr auto INVENTORY_PATH = "/xyz/openbmc_project/inventory";
constexpr auto INVENTORY_INTF = "xyz.openbmc_project.Inventory.Manager";
+struct FreeEvDev
+{
+ void operator()(struct libevdev* device) const
+ {
+ libevdev_free(device);
+ }
+};
+
class CoolingType
{
using Property = std::string;
@@ -39,6 +48,7 @@ class CoolingType
*/
CoolingType(sdbusplus::bus::bus& bus) : bus(bus)
{
+ //TODO: Issue openbmc/openbmc#1531 - means to default properties.
}
/**
@@ -52,15 +62,16 @@ class CoolingType
/**
* @brief Updates the inventory properties for CoolingType.
*
- * @param[in] path - D-Bus path
+ * @param[in] path - Path to object to update
*/
- void updateInventory(const std::string&);
+ void updateInventory(const std::string& path);
/**
- * @brief Setup the GPIO device for reading cooling type.
+ * @brief Setup and read the GPIO device for reading cooling type.
*
- * @param[in] - Path to object to update
+ * @param[in] path - Path to the GPIO device file to read
+ * @param[in] pin - Event/key code to read (pin)
*/
- void setupGpio(const std::string&);
+ void readGpio(const std::string& path, unsigned int pin);
private:
/** @brief Connection for sdbusplus bus */
@@ -73,11 +84,11 @@ class CoolingType
/**
* @brief Construct the inventory object map for CoolingType.
*
- * @param[in] - Path to object to update
+ * @param[in] objpath - Path to object to update
*
* @return The inventory object map to update inventory
- */
- ObjectMap getObjectMap(const std::string&);
+ */
+ ObjectMap getObjectMap(const std::string& objpath);
};
diff --git a/cooling-type/main.cpp b/cooling-type/main.cpp
index 91934ea..caa4e88 100644
--- a/cooling-type/main.cpp
+++ b/cooling-type/main.cpp
@@ -8,14 +8,6 @@
using namespace phosphor::cooling::type;
using namespace phosphor::logging;
-// Utility function to find the device string for a given pin name.
-std::string findGpio(std::string pinName)
-{
- std::string path = "/dev/null";
- //TODO
- return path;
-}
-
int main(int argc, char* argv[])
{
auto rc = -1;
@@ -37,36 +29,46 @@ int main(int argc, char* argv[])
auto bus = sdbusplus::bus::new_default();
CoolingType coolingType(bus);
- auto gpiopin = (options)["gpio"];
- if (gpiopin != ArgumentParser::empty_string)
+ try
{
- try
+ auto air = (options)["air"];
+ if (air != ArgumentParser::empty_string)
{
- auto gpiopath = findGpio(gpiopin);
- coolingType.setupGpio(gpiopath);
+ coolingType.setAirCooled();
}
- catch (std::exception& err)
+
+ auto water = (options)["water"];
+ if (water != ArgumentParser::empty_string)
{
- rc = -1;
- log<phosphor::logging::level::ERR>(err.what());
+ coolingType.setWaterCooled();
}
- }
- auto air = (options)["air"];
- if (air != ArgumentParser::empty_string)
- {
- coolingType.setAirCooled();
+ auto gpiopath = (options)["dev"];
+ if (gpiopath != ArgumentParser::empty_string)
+ {
+ auto keycode = (options)["event"];
+ if (keycode != ArgumentParser::empty_string)
+ {
+ auto gpiocode = std::stoul(keycode);
+ coolingType.readGpio(gpiopath, gpiocode);
+ }
+ else
+ {
+ log<level::ERR>("--event=<keycode> argument required\n");
+ exit(-1);
+ }
+ }
+
+ coolingType.updateInventory(objpath);
+ rc = 0;
}
- auto water = (options)["water"];
- if (water != ArgumentParser::empty_string)
+ catch (std::exception& err)
{
- coolingType.setWaterCooled();
+ rc = -1;
+ log<phosphor::logging::level::ERR>(err.what());
}
- coolingType.updateInventory(objpath);
-
- rc = 0;
}
return rc;
OpenPOWER on IntegriCloud