From 9df0e16e00338ea267c71a2bf3c314d39e8961be Mon Sep 17 00:00:00 2001 From: Brad Bishop Date: Sat, 22 Apr 2017 14:19:45 -0400 Subject: build: Move presence to a subdirectory Change-Id: I33b28922107b9b041de3699e4a6eebd3d05ebdef Signed-off-by: Brad Bishop --- Makefile.am | 29 +++------- configure.ac | 6 +-- control/Makefile.am | 2 +- example/fan-detect.yaml | 24 --------- fan_detect_defs.hpp | 9 ---- fan_enclosure.cpp | 105 ------------------------------------ fan_enclosure.hpp | 114 --------------------------------------- fan_properties.hpp | 22 -------- gen-fan-detect-defs.py | 72 ------------------------- presence/Makefile.am | 25 +++++++++ presence/example/fan-detect.yaml | 24 +++++++++ presence/fan_detect_defs.hpp | 9 ++++ presence/fan_enclosure.cpp | 105 ++++++++++++++++++++++++++++++++++++ presence/fan_enclosure.hpp | 114 +++++++++++++++++++++++++++++++++++++++ presence/fan_properties.hpp | 22 ++++++++ presence/gen-fan-detect-defs.py | 72 +++++++++++++++++++++++++ presence/sensor_base.hpp | 59 ++++++++++++++++++++ presence/tach_detect.cpp | 58 ++++++++++++++++++++ presence/tach_sensor.cpp | 69 ++++++++++++++++++++++++ presence/tach_sensor.hpp | 107 ++++++++++++++++++++++++++++++++++++ sensor_base.hpp | 59 -------------------- tach_detect.cpp | 58 -------------------- tach_sensor.cpp | 69 ------------------------ tach_sensor.hpp | 107 ------------------------------------ 24 files changed, 676 insertions(+), 664 deletions(-) delete mode 100644 example/fan-detect.yaml delete mode 100644 fan_detect_defs.hpp delete mode 100644 fan_enclosure.cpp delete mode 100644 fan_enclosure.hpp delete mode 100644 fan_properties.hpp delete mode 100755 gen-fan-detect-defs.py create mode 100644 presence/Makefile.am create mode 100644 presence/example/fan-detect.yaml create mode 100644 presence/fan_detect_defs.hpp create mode 100644 presence/fan_enclosure.cpp create mode 100644 presence/fan_enclosure.hpp create mode 100644 presence/fan_properties.hpp create mode 100755 presence/gen-fan-detect-defs.py create mode 100644 presence/sensor_base.hpp create mode 100644 presence/tach_detect.cpp create mode 100644 presence/tach_sensor.cpp create mode 100644 presence/tach_sensor.hpp delete mode 100644 sensor_base.hpp delete mode 100644 tach_detect.cpp delete mode 100644 tach_sensor.cpp delete mode 100644 tach_sensor.hpp diff --git a/Makefile.am b/Makefile.am index 6180d1e..c3dee8b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,25 +1,12 @@ AM_DEFAULT_SOURCE_EXT = .cpp -sbin_PROGRAMS = \ - phosphor-fan-presence-tach - -phosphor_fan_presence_tach_SOURCES = \ - fan_enclosure.cpp \ - tach_sensor.cpp \ - tach_detect.cpp \ +noinst_LTLIBRARIES = libfan.la +libfan_la_LDFLAGS = -static +libfan_la_LIBADD = \ + $(SDBUSPLUS_LIBS) +libfan_la_CXXFLAGS = + $(SDBUSPLUS_CFLAGS) +libfan_la_SOURCES = \ utility.cpp -nodist_phosphor_fan_presence_tach_SOURCES = \ - fan_detect_defs.cpp - -phosphor_fan_presence_tach_LDFLAGS = $(SDBUSPLUS_LIBS) $(PHOSPHOR_LOGGING_LIBS) -phosphor_fan_presence_tach_CXXFLAGS = \ - $(SDBUSPLUS_CFLAGS) \ - $(PHOSPHOR_LOGGING_CFLAGS) - -BUILT_SOURCES = fan_detect_defs.cpp -CLEANFILES = fan_detect_defs.cpp - -fan_detect_defs.cpp: ${srcdir}/gen-fan-detect-defs.py - $(AM_V_GEN)$(GEN_FAN_DETECT_DEFS) > $@ -SUBDIRS = control \ No newline at end of file +SUBDIRS = . presence control diff --git a/configure.ac b/configure.ac index 2c083ca..c3d5d75 100644 --- a/configure.ac +++ b/configure.ac @@ -35,12 +35,12 @@ LT_INIT # Required for systemd linking AC_ARG_VAR(FAN_DETECT_YAML_FILE, [The fan presence detection definition file to use]) AS_IF([test "x$FAN_DETECT_YAML_FILE" == "x"], -[FAN_DETECT_YAML_FILE="${srcdir}/example/fan-detect.yaml"]) +[FAN_DETECT_YAML_FILE="${srcdir}/presence/example/fan-detect.yaml"]) AC_DEFINE_UNQUOTED([FAN_DETECT_YAML_FILE], ["$FAN_DETECT_YAML_FILE"], [The fan presence detection definition file to use]) # Create configured output AC_SUBST([GEN_FAN_DETECT_DEFS], -[$PYTHON ${srcdir}/gen-fan-detect-defs.py -y $FAN_DETECT_YAML_FILE]) -AC_CONFIG_FILES([Makefile control/Makefile]) +[$PYTHON ${srcdir}/presence/gen-fan-detect-defs.py -y $FAN_DETECT_YAML_FILE]) +AC_CONFIG_FILES([Makefile presence/Makefile control/Makefile]) AC_OUTPUT diff --git a/control/Makefile.am b/control/Makefile.am index a9b8133..73dea93 100644 --- a/control/Makefile.am +++ b/control/Makefile.am @@ -1,5 +1,5 @@ AM_DEFAULT_SOURCE_EXT = .cpp -AM_CPPFLAGS = -I${top_src_dir} +AM_CPPFLAGS = -iquote ${top_srcdir} sbin_PROGRAMS = \ phosphor-fan-control diff --git a/example/fan-detect.yaml b/example/fan-detect.yaml deleted file mode 100644 index 5a9e1bd..0000000 --- a/example/fan-detect.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Example fan presence detection definitions - -# List each fan requiring presence detection and creation of an inventory object -# within a system with the following parameters. The 'Detection' method must -# have an associated fan presence detection application to properly handle -# detecting fans using that type. - -#- [Detection method]: -# - PrettyName: [pretty name of the fan] -# Sensors: [List of sensors associated with this fan enclosure] -# - i.e) For tach feedback detection: -# The hwmon name for a detected fan rotor's tach feedback -# For gpio detection: -# The gpio pin name for the fan's presence line -# Inventory: [The system inventory location for the fan] -# Description: (Optional) - -# Example entry for a single fan's presence detected by 'Tach' feedback -#- Tach: -# - PrettyName: fan0 -# Sensors: -# - fan0 -# Inventory: /system/chassis/fan0 -# Description: Chassis location A1 diff --git a/fan_detect_defs.hpp b/fan_detect_defs.hpp deleted file mode 100644 index 6c49366..0000000 --- a/fan_detect_defs.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include -#include -#include -#include "fan_properties.hpp" - -extern const std::map> fanDetectMap; diff --git a/fan_enclosure.cpp b/fan_enclosure.cpp deleted file mode 100644 index 262876e..0000000 --- a/fan_enclosure.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright © 2017 IBM Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include "fan_enclosure.hpp" -#include "utility.hpp" - -namespace phosphor -{ -namespace fan -{ -namespace presence -{ - -using namespace phosphor::logging; - -//TODO Should get these from phosphor-inventory-manager config.h -constexpr auto INVENTORY_PATH = "/xyz/openbmc_project/inventory"; -constexpr auto INVENTORY_INTF = "xyz.openbmc_project.Inventory.Manager"; - -presenceState FanEnclosure::getCurPresState() -{ - auto presPred = [](auto const& s) {return s->isPresent();}; - // Determine if all sensors show fan is not present - auto isPresent = std::any_of(sensors.begin(), - sensors.end(), - presPred); - - return (isPresent) ? PRESENT : NOT_PRESENT; -} - -FanEnclosure::ObjectMap FanEnclosure::getObjectMap(const bool curPresState) -{ - ObjectMap invObj; - InterfaceMap invIntf; - PropertyMap invProp; - - invProp.emplace("Present", curPresState); - invProp.emplace("PrettyName", fanDesc); - invIntf.emplace("xyz.openbmc_project.Inventory.Item", std::move(invProp)); - Object fanInvPath = invPath; - invObj.emplace(std::move(fanInvPath), std::move(invIntf)); - - return invObj; -} - -void FanEnclosure::updInventory() -{ - auto curPresState = getCurPresState(); - // Only update inventory when presence state changed - if (presState != curPresState) - { - // Get inventory object for this fan - ObjectMap invObj = getObjectMap(curPresState); - // Get inventory manager service name from mapper - std::string invService; - try - { - invService = getInvService(bus); - } - catch (const std::runtime_error& err) - { - log(err.what()); - return; - } - // Update inventory for this fan - auto invMsg = bus.new_method_call(invService.c_str(), - INVENTORY_PATH, - INVENTORY_INTF, - "Notify"); - invMsg.append(std::move(invObj)); - auto invMgrResponseMsg = bus.call(invMsg); - if (invMgrResponseMsg.is_method_error()) - { - log( - "Error in inventory manager call to update inventory"); - return; - } - // Inventory updated, set presence state to current - presState = curPresState; - } -} - -void FanEnclosure::addSensor( - std::unique_ptr&& sensor) -{ - FanEnclosure::sensors.push_back(std::move(sensor)); -} - -} // namespace presence -} // namespace fan -} // namespace phosphor diff --git a/fan_enclosure.hpp b/fan_enclosure.hpp deleted file mode 100644 index 8f5cfdf..0000000 --- a/fan_enclosure.hpp +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -#include -#include "fan_properties.hpp" -#include "sensor_base.hpp" - - -namespace phosphor -{ -namespace fan -{ -namespace presence -{ - -/** - * @brief Specifies the defined presence states of a fan enclosure - */ -typedef enum presenceState -{ - NOT_PRESENT, - PRESENT, - UNKNOWN -} presenceState; - -/** - * @class FanEnclosure - * @brief OpenBMC fan enclosure inventory presence implementation - * @details Inventory is based on the fan enclosure being present or not. This - * class represents that fan enclosure and updates its presences status within - * its inventory object based on the status of all its sensors. - */ -class FanEnclosure -{ - using Property = std::string; - using Value = sdbusplus::message::variant; - // Association between property and its value - using PropertyMap = std::map; - using Interface = std::string; - // Association between interface and the dbus property - using InterfaceMap = std::map; - using Object = sdbusplus::message::object_path; - // Association between object and the interface - using ObjectMap = std::map; - - public: - FanEnclosure() = delete; - FanEnclosure(const FanEnclosure&) = delete; - FanEnclosure(FanEnclosure&&) = default; - FanEnclosure& operator=(const FanEnclosure&) = delete; - FanEnclosure& operator=(FanEnclosure&&) = delete; - ~FanEnclosure() = default; - - /** - * @brief Constructs Fan Enclosure Object - * - * @param[in] bus - Dbus bus object - * @param[in] fanProp - Fan enclosure properties - */ - FanEnclosure(sdbusplus::bus::bus& bus, - const phosphor::fan::Properties& fanProp) : - bus(bus), - invPath(std::get<0>(fanProp)), - fanDesc(std::get<1>(fanProp)) - { - //Add this fan to inventory - updInventory(); - } - - /** - * @brief Update inventory when the determined presence of this fan - * enclosure has changed - */ - void updInventory(); - /** - * @brief Add a sensor association to this fan enclosure - * - * @param[in] sensor - Sensor associated to this fan enclosure - */ - void addSensor( - std::unique_ptr&& sensor); - - private: - /** @brief Connection for sdbusplus bus */ - sdbusplus::bus::bus& bus; - /** @brief Inventory path for this fan enclosure */ - const std::string invPath; - /** @brief Description used as 'PrettyName' on inventory object */ - const std::string fanDesc; - /** @brief List of sensors associated with this fan enclosure */ - std::vector> sensors; - /** @brief Last known presence state of this fan enclosure */ - presenceState presState = UNKNOWN; - - /** - * @brief Get the current presence state based on all sensors - * - * @return Current presence state determined from all sensors - */ - presenceState getCurPresState(); - - /** - * @brief Construct the inventory object map - * - * @param[in] Current presence state - * - * @return The inventory object map to update inventory - */ - ObjectMap getObjectMap(bool curPresState); - -}; - -} // namespace presence -} // namespace fan -} // namespace phosphor diff --git a/fan_properties.hpp b/fan_properties.hpp deleted file mode 100644 index 296318d..0000000 --- a/fan_properties.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace phosphor -{ -namespace fan -{ - -/** - * @brief Fan enclosure properties - * @details Contains the inventory path, description and list of sensors - */ -using Properties = std::tuple>; - -} // namespace fan -} // namespace phosphor diff --git a/gen-fan-detect-defs.py b/gen-fan-detect-defs.py deleted file mode 100755 index 1bc980a..0000000 --- a/gen-fan-detect-defs.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python - -""" -This script parses the given fan presence definition yaml file and generates -a header file based on the defined methods for determining when a fan is -present. -""" - -import os -import sys -import yaml -from argparse import ArgumentParser -from mako.template import Template - -tmpl = '''/* This is a generated file. */ -#include "fan_detect_defs.hpp" - -const std::map> -fanDetectMap = { -%for methods in presence: - %for method in methods: - <% m = method.lower() %> \ - {"${m}", { - %for fan in methods[method]: - std::make_tuple("${fan['Inventory']}", - "${fan['PrettyName']}", - std::vector{ - %for s in fan['Sensors']: - "${s}", - %endfor - }), - %endfor - %endfor - }}, -%endfor -}; -''' - - -def get_filename(): - """ - Constructs and returns the fully qualified header filename. - """ - script_dir = os.path.dirname(os.path.abspath(__file__)) - header_file = os.path.join(script_dir, "fan_detect_defs.cpp") - - return header_file - - -if __name__ == '__main__': - parser = ArgumentParser() - # Input yaml containing how each fan's presence detection should be done - parser.add_argument("-y", "--yaml", dest="pres_yaml", - default= - "example/fan-detect.yaml", - help= - "Input fan presences definition yaml file to parse") - args = parser.parse_args(sys.argv[1:]) - - # Verify given yaml file exists - yaml_file = os.path.abspath(args.pres_yaml) - if not os.path.isfile(yaml_file): - print "Unable to find input yaml file " + yaml_file - exit(1) - - with open(yaml_file, 'r') as yaml_input: - presence_data = yaml.safe_load(yaml_input) or {} - - output_file = get_filename() - - with open(output_file, 'w') as out: - out.write(Template(tmpl).render(presence=presence_data)) diff --git a/presence/Makefile.am b/presence/Makefile.am new file mode 100644 index 0000000..10a7363 --- /dev/null +++ b/presence/Makefile.am @@ -0,0 +1,25 @@ +AM_DEFAULT_SOURCE_EXT = .cpp +AM_CPPFLAGS = -iquote ${top_srcdir} + +sbin_PROGRAMS = \ + phosphor-fan-presence-tach + +phosphor_fan_presence_tach_SOURCES = \ + fan_enclosure.cpp \ + tach_sensor.cpp \ + tach_detect.cpp +nodist_phosphor_fan_presence_tach_SOURCES = \ + fan_detect_defs.cpp + +phosphor_fan_presence_tach_LDADD = \ + $(top_builddir)/libfan.la \ + $(SDBUSPLUS_LIBS) \ + $(PHOSPHOR_LOGGING_LIBS) +phosphor_fan_presence_tach_CXXFLAGS = \ + $(SDBUSPLUS_CFLAGS) \ + $(PHOSPHOR_LOGGING_CFLAGS) + +BUILT_SOURCES = fan_detect_defs.cpp + +fan_detect_defs.cpp: ${srcdir}/gen-fan-detect-defs.py + $(AM_V_GEN)$(GEN_FAN_DETECT_DEFS) > $@ diff --git a/presence/example/fan-detect.yaml b/presence/example/fan-detect.yaml new file mode 100644 index 0000000..5a9e1bd --- /dev/null +++ b/presence/example/fan-detect.yaml @@ -0,0 +1,24 @@ +# Example fan presence detection definitions + +# List each fan requiring presence detection and creation of an inventory object +# within a system with the following parameters. The 'Detection' method must +# have an associated fan presence detection application to properly handle +# detecting fans using that type. + +#- [Detection method]: +# - PrettyName: [pretty name of the fan] +# Sensors: [List of sensors associated with this fan enclosure] +# - i.e) For tach feedback detection: +# The hwmon name for a detected fan rotor's tach feedback +# For gpio detection: +# The gpio pin name for the fan's presence line +# Inventory: [The system inventory location for the fan] +# Description: (Optional) + +# Example entry for a single fan's presence detected by 'Tach' feedback +#- Tach: +# - PrettyName: fan0 +# Sensors: +# - fan0 +# Inventory: /system/chassis/fan0 +# Description: Chassis location A1 diff --git a/presence/fan_detect_defs.hpp b/presence/fan_detect_defs.hpp new file mode 100644 index 0000000..6c49366 --- /dev/null +++ b/presence/fan_detect_defs.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include +#include +#include +#include "fan_properties.hpp" + +extern const std::map> fanDetectMap; diff --git a/presence/fan_enclosure.cpp b/presence/fan_enclosure.cpp new file mode 100644 index 0000000..262876e --- /dev/null +++ b/presence/fan_enclosure.cpp @@ -0,0 +1,105 @@ +/** + * Copyright © 2017 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "fan_enclosure.hpp" +#include "utility.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +using namespace phosphor::logging; + +//TODO Should get these from phosphor-inventory-manager config.h +constexpr auto INVENTORY_PATH = "/xyz/openbmc_project/inventory"; +constexpr auto INVENTORY_INTF = "xyz.openbmc_project.Inventory.Manager"; + +presenceState FanEnclosure::getCurPresState() +{ + auto presPred = [](auto const& s) {return s->isPresent();}; + // Determine if all sensors show fan is not present + auto isPresent = std::any_of(sensors.begin(), + sensors.end(), + presPred); + + return (isPresent) ? PRESENT : NOT_PRESENT; +} + +FanEnclosure::ObjectMap FanEnclosure::getObjectMap(const bool curPresState) +{ + ObjectMap invObj; + InterfaceMap invIntf; + PropertyMap invProp; + + invProp.emplace("Present", curPresState); + invProp.emplace("PrettyName", fanDesc); + invIntf.emplace("xyz.openbmc_project.Inventory.Item", std::move(invProp)); + Object fanInvPath = invPath; + invObj.emplace(std::move(fanInvPath), std::move(invIntf)); + + return invObj; +} + +void FanEnclosure::updInventory() +{ + auto curPresState = getCurPresState(); + // Only update inventory when presence state changed + if (presState != curPresState) + { + // Get inventory object for this fan + ObjectMap invObj = getObjectMap(curPresState); + // Get inventory manager service name from mapper + std::string invService; + try + { + invService = getInvService(bus); + } + catch (const std::runtime_error& err) + { + log(err.what()); + return; + } + // Update inventory for this fan + auto invMsg = bus.new_method_call(invService.c_str(), + INVENTORY_PATH, + INVENTORY_INTF, + "Notify"); + invMsg.append(std::move(invObj)); + auto invMgrResponseMsg = bus.call(invMsg); + if (invMgrResponseMsg.is_method_error()) + { + log( + "Error in inventory manager call to update inventory"); + return; + } + // Inventory updated, set presence state to current + presState = curPresState; + } +} + +void FanEnclosure::addSensor( + std::unique_ptr&& sensor) +{ + FanEnclosure::sensors.push_back(std::move(sensor)); +} + +} // namespace presence +} // namespace fan +} // namespace phosphor diff --git a/presence/fan_enclosure.hpp b/presence/fan_enclosure.hpp new file mode 100644 index 0000000..8f5cfdf --- /dev/null +++ b/presence/fan_enclosure.hpp @@ -0,0 +1,114 @@ +#pragma once + +#include +#include "fan_properties.hpp" +#include "sensor_base.hpp" + + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +/** + * @brief Specifies the defined presence states of a fan enclosure + */ +typedef enum presenceState +{ + NOT_PRESENT, + PRESENT, + UNKNOWN +} presenceState; + +/** + * @class FanEnclosure + * @brief OpenBMC fan enclosure inventory presence implementation + * @details Inventory is based on the fan enclosure being present or not. This + * class represents that fan enclosure and updates its presences status within + * its inventory object based on the status of all its sensors. + */ +class FanEnclosure +{ + using Property = std::string; + using Value = sdbusplus::message::variant; + // Association between property and its value + using PropertyMap = std::map; + using Interface = std::string; + // Association between interface and the dbus property + using InterfaceMap = std::map; + using Object = sdbusplus::message::object_path; + // Association between object and the interface + using ObjectMap = std::map; + + public: + FanEnclosure() = delete; + FanEnclosure(const FanEnclosure&) = delete; + FanEnclosure(FanEnclosure&&) = default; + FanEnclosure& operator=(const FanEnclosure&) = delete; + FanEnclosure& operator=(FanEnclosure&&) = delete; + ~FanEnclosure() = default; + + /** + * @brief Constructs Fan Enclosure Object + * + * @param[in] bus - Dbus bus object + * @param[in] fanProp - Fan enclosure properties + */ + FanEnclosure(sdbusplus::bus::bus& bus, + const phosphor::fan::Properties& fanProp) : + bus(bus), + invPath(std::get<0>(fanProp)), + fanDesc(std::get<1>(fanProp)) + { + //Add this fan to inventory + updInventory(); + } + + /** + * @brief Update inventory when the determined presence of this fan + * enclosure has changed + */ + void updInventory(); + /** + * @brief Add a sensor association to this fan enclosure + * + * @param[in] sensor - Sensor associated to this fan enclosure + */ + void addSensor( + std::unique_ptr&& sensor); + + private: + /** @brief Connection for sdbusplus bus */ + sdbusplus::bus::bus& bus; + /** @brief Inventory path for this fan enclosure */ + const std::string invPath; + /** @brief Description used as 'PrettyName' on inventory object */ + const std::string fanDesc; + /** @brief List of sensors associated with this fan enclosure */ + std::vector> sensors; + /** @brief Last known presence state of this fan enclosure */ + presenceState presState = UNKNOWN; + + /** + * @brief Get the current presence state based on all sensors + * + * @return Current presence state determined from all sensors + */ + presenceState getCurPresState(); + + /** + * @brief Construct the inventory object map + * + * @param[in] Current presence state + * + * @return The inventory object map to update inventory + */ + ObjectMap getObjectMap(bool curPresState); + +}; + +} // namespace presence +} // namespace fan +} // namespace phosphor diff --git a/presence/fan_properties.hpp b/presence/fan_properties.hpp new file mode 100644 index 0000000..296318d --- /dev/null +++ b/presence/fan_properties.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + + +namespace phosphor +{ +namespace fan +{ + +/** + * @brief Fan enclosure properties + * @details Contains the inventory path, description and list of sensors + */ +using Properties = std::tuple>; + +} // namespace fan +} // namespace phosphor diff --git a/presence/gen-fan-detect-defs.py b/presence/gen-fan-detect-defs.py new file mode 100755 index 0000000..1bc980a --- /dev/null +++ b/presence/gen-fan-detect-defs.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +""" +This script parses the given fan presence definition yaml file and generates +a header file based on the defined methods for determining when a fan is +present. +""" + +import os +import sys +import yaml +from argparse import ArgumentParser +from mako.template import Template + +tmpl = '''/* This is a generated file. */ +#include "fan_detect_defs.hpp" + +const std::map> +fanDetectMap = { +%for methods in presence: + %for method in methods: + <% m = method.lower() %> \ + {"${m}", { + %for fan in methods[method]: + std::make_tuple("${fan['Inventory']}", + "${fan['PrettyName']}", + std::vector{ + %for s in fan['Sensors']: + "${s}", + %endfor + }), + %endfor + %endfor + }}, +%endfor +}; +''' + + +def get_filename(): + """ + Constructs and returns the fully qualified header filename. + """ + script_dir = os.path.dirname(os.path.abspath(__file__)) + header_file = os.path.join(script_dir, "fan_detect_defs.cpp") + + return header_file + + +if __name__ == '__main__': + parser = ArgumentParser() + # Input yaml containing how each fan's presence detection should be done + parser.add_argument("-y", "--yaml", dest="pres_yaml", + default= + "example/fan-detect.yaml", + help= + "Input fan presences definition yaml file to parse") + args = parser.parse_args(sys.argv[1:]) + + # Verify given yaml file exists + yaml_file = os.path.abspath(args.pres_yaml) + if not os.path.isfile(yaml_file): + print "Unable to find input yaml file " + yaml_file + exit(1) + + with open(yaml_file, 'r') as yaml_input: + presence_data = yaml.safe_load(yaml_input) or {} + + output_file = get_filename() + + with open(output_file, 'w') as out: + out.write(Template(tmpl).render(presence=presence_data)) diff --git a/presence/sensor_base.hpp b/presence/sensor_base.hpp new file mode 100644 index 0000000..c206e70 --- /dev/null +++ b/presence/sensor_base.hpp @@ -0,0 +1,59 @@ +#pragma once + + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +// Forward declare FanEnclosure +class FanEnclosure; +/** + * @class Sensor + * @brief Base sensor implementation to be extended + * @details A type of presence detection sensor would extend this to override + * how presences is determined by the fan enclosure containing that type + */ +class Sensor +{ + public: + Sensor() = delete; + Sensor(const Sensor&) = delete; + Sensor(Sensor&&) = delete; + Sensor& operator=(const Sensor&) = delete; + Sensor& operator=(Sensor&&) = delete; + virtual ~Sensor() = default; + + /** + * @brief Constructs Sensor Object + * + * @param[in] id - ID name of this sensor + * @param[in] fanEnc - Reference to the fan enclosure with this sensor + */ + Sensor(const std::string& id, + FanEnclosure& fanEnc) : + id(id), + fanEnc(fanEnc) + { + //Nothing to do here + } + + /** + * @brief Presence function that must be implemented within the derived + * type of sensor's implementation on how presence is determined + */ + virtual bool isPresent() = 0; + + protected: + /** @brief ID name of this sensor */ + const std::string id; + /** @brief Reference to the fan enclosure containing this sensor */ + FanEnclosure& fanEnc; + +}; + +} // namespace presence +} // namespace fan +} // namespace phosphor diff --git a/presence/tach_detect.cpp b/presence/tach_detect.cpp new file mode 100644 index 0000000..2449f82 --- /dev/null +++ b/presence/tach_detect.cpp @@ -0,0 +1,58 @@ +/** + * Copyright © 2017 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "fan_enclosure.hpp" +#include "fan_detect_defs.hpp" +#include "tach_sensor.hpp" + + +int main(void) +{ + auto bus = sdbusplus::bus::new_default(); + + std::vector> fans; + + for (auto const& detectMap: fanDetectMap) + { + if (detectMap.first == "tach") + { + for (auto const& fanProp: detectMap.second) + { + auto fan = std::make_unique< + phosphor::fan::presence::FanEnclosure>(bus, + fanProp); + for (auto const &fanSensor: std::get<2>(fanProp)) + { + auto sensor = std::make_unique< + phosphor::fan::presence::TachSensor>(bus, + fanSensor, + *fan); + fan->addSensor(std::move(sensor)); + } + fans.push_back(std::move(fan)); + } + } + } + + while (true) + { + // Respond to dbus signals + bus.process_discard(); + bus.wait(); + } + return 0; +} diff --git a/presence/tach_sensor.cpp b/presence/tach_sensor.cpp new file mode 100644 index 0000000..c21478b --- /dev/null +++ b/presence/tach_sensor.cpp @@ -0,0 +1,69 @@ +/** + * Copyright © 2017 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "tach_sensor.hpp" +#include "fan_enclosure.hpp" + + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +bool TachSensor::isPresent() +{ + return (tach != 0); +} + +// Tach signal callback handler +int TachSensor::handleTachChangeSignal(sd_bus_message* msg, + void* usrData, + sd_bus_error* err) +{ + auto sdbpMsg = sdbusplus::message::message(msg); + static_cast(usrData)->handleTachChange(sdbpMsg, err); + return 0; +} + +void TachSensor::handleTachChange(sdbusplus::message::message& sdbpMsg, + sd_bus_error* err) +{ + std::string msgSensor; + std::map> msgData; + sdbpMsg.read(msgSensor, msgData); + + // TODO openbmc/phosphor-fan-presence#5 + // Update to use 'arg0namespace' match option to reduce dbus traffic + // Find interface with value property + if (msgSensor.compare("xyz.openbmc_project.Sensor.Value") == 0) + { + // Find the 'Value' property containing tach + auto valPropMap = msgData.find("Value"); + if (valPropMap != msgData.end()) + { + tach = sdbusplus::message::variant_ns::get( + valPropMap->second); + } + } + // Update inventory according to latest tach reported + fanEnc.updInventory(); +} + +} // namespace presence +} // namespace fan +} // namespace phosphor diff --git a/presence/tach_sensor.hpp b/presence/tach_sensor.hpp new file mode 100644 index 0000000..90d955b --- /dev/null +++ b/presence/tach_sensor.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include +#include +#include "sensor_base.hpp" + + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +/** + * @class TachSensor + * @brief OpenBMC Tach feedback sensor presence implementation + * @details Derived sensor type that uses the tach feedback value to determine + * the presence of the fan enclosure that contains this sensor + */ +class TachSensor : public Sensor +{ + public: + TachSensor() = delete; + TachSensor(const TachSensor&) = delete; + TachSensor(TachSensor&&) = delete; + TachSensor& operator=(const TachSensor&) = delete; + TachSensor& operator=(TachSensor&&) = delete; + ~TachSensor() = default; + + /** + * @brief Constructs Tach Sensor Object + * + * @param[in] bus - Dbus bus object + * @param[in] id - ID name of this sensor + * @param[in] fanEnc - Reference to the fan enclosure with this sensor + */ + TachSensor( + sdbusplus::bus::bus& bus, + const std::string& id, + FanEnclosure& fanEnc) : + Sensor(id, fanEnc), + bus(bus), + tachSignal(bus, + match(id).c_str(), + handleTachChangeSignal, + this) + { + // Nothing to do here + } + + /** + * @brief Determine the presence of this sensor using the tach feedback + * + * @return Presence state based on tach feedback + */ + bool isPresent(); + + private: + /** @brief Connection for sdbusplus bus */ + sdbusplus::bus::bus& bus; + /** @brief Used to subscribe to dbus signals */ + sdbusplus::server::match::match tachSignal; + /** @brief Tach speed value given from the signal */ + int64_t tach = 0; + + /** + * @brief Appends the fan sensor id to construct a match string + * + * @param[in] id - Fan sensor id + * + * @return Match string to register signal for the fan sensor id + */ + static std::string match(const std::string& id) + { + return std::string("type='signal'," + "interface='org.freedesktop.DBus.Properties'," + "member='PropertiesChanged'," + "path='/xyz/openbmc_project/sensors/fan_tach/" + + id + "'"); + } + /** + * @brief Callback function on tach change signals + * + * @param[out] msg - Data associated with the subscribed signal + * @param[out] data - Pointer to this tach sensor object instance + * @param[out] err - Contains any sdbus error reference if occurred + * + * @return 0 + */ + static int handleTachChangeSignal(sd_bus_message* msg, + void* data, + sd_bus_error* err); + /** + * @brief Determine & handle when the signal was a tach change + * + * @param[in] msg - Expanded sdbusplus message data + * @param[in] err - Contains any sdbus error reference if occurred + */ + void handleTachChange(sdbusplus::message::message& msg, + sd_bus_error* err); + +}; + +} // namespace presence +} // namespace fan +} // namespace phosphor diff --git a/sensor_base.hpp b/sensor_base.hpp deleted file mode 100644 index c206e70..0000000 --- a/sensor_base.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - - -namespace phosphor -{ -namespace fan -{ -namespace presence -{ - -// Forward declare FanEnclosure -class FanEnclosure; -/** - * @class Sensor - * @brief Base sensor implementation to be extended - * @details A type of presence detection sensor would extend this to override - * how presences is determined by the fan enclosure containing that type - */ -class Sensor -{ - public: - Sensor() = delete; - Sensor(const Sensor&) = delete; - Sensor(Sensor&&) = delete; - Sensor& operator=(const Sensor&) = delete; - Sensor& operator=(Sensor&&) = delete; - virtual ~Sensor() = default; - - /** - * @brief Constructs Sensor Object - * - * @param[in] id - ID name of this sensor - * @param[in] fanEnc - Reference to the fan enclosure with this sensor - */ - Sensor(const std::string& id, - FanEnclosure& fanEnc) : - id(id), - fanEnc(fanEnc) - { - //Nothing to do here - } - - /** - * @brief Presence function that must be implemented within the derived - * type of sensor's implementation on how presence is determined - */ - virtual bool isPresent() = 0; - - protected: - /** @brief ID name of this sensor */ - const std::string id; - /** @brief Reference to the fan enclosure containing this sensor */ - FanEnclosure& fanEnc; - -}; - -} // namespace presence -} // namespace fan -} // namespace phosphor diff --git a/tach_detect.cpp b/tach_detect.cpp deleted file mode 100644 index 2449f82..0000000 --- a/tach_detect.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright © 2017 IBM Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include "fan_enclosure.hpp" -#include "fan_detect_defs.hpp" -#include "tach_sensor.hpp" - - -int main(void) -{ - auto bus = sdbusplus::bus::new_default(); - - std::vector> fans; - - for (auto const& detectMap: fanDetectMap) - { - if (detectMap.first == "tach") - { - for (auto const& fanProp: detectMap.second) - { - auto fan = std::make_unique< - phosphor::fan::presence::FanEnclosure>(bus, - fanProp); - for (auto const &fanSensor: std::get<2>(fanProp)) - { - auto sensor = std::make_unique< - phosphor::fan::presence::TachSensor>(bus, - fanSensor, - *fan); - fan->addSensor(std::move(sensor)); - } - fans.push_back(std::move(fan)); - } - } - } - - while (true) - { - // Respond to dbus signals - bus.process_discard(); - bus.wait(); - } - return 0; -} diff --git a/tach_sensor.cpp b/tach_sensor.cpp deleted file mode 100644 index c21478b..0000000 --- a/tach_sensor.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright © 2017 IBM Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include "tach_sensor.hpp" -#include "fan_enclosure.hpp" - - -namespace phosphor -{ -namespace fan -{ -namespace presence -{ - -bool TachSensor::isPresent() -{ - return (tach != 0); -} - -// Tach signal callback handler -int TachSensor::handleTachChangeSignal(sd_bus_message* msg, - void* usrData, - sd_bus_error* err) -{ - auto sdbpMsg = sdbusplus::message::message(msg); - static_cast(usrData)->handleTachChange(sdbpMsg, err); - return 0; -} - -void TachSensor::handleTachChange(sdbusplus::message::message& sdbpMsg, - sd_bus_error* err) -{ - std::string msgSensor; - std::map> msgData; - sdbpMsg.read(msgSensor, msgData); - - // TODO openbmc/phosphor-fan-presence#5 - // Update to use 'arg0namespace' match option to reduce dbus traffic - // Find interface with value property - if (msgSensor.compare("xyz.openbmc_project.Sensor.Value") == 0) - { - // Find the 'Value' property containing tach - auto valPropMap = msgData.find("Value"); - if (valPropMap != msgData.end()) - { - tach = sdbusplus::message::variant_ns::get( - valPropMap->second); - } - } - // Update inventory according to latest tach reported - fanEnc.updInventory(); -} - -} // namespace presence -} // namespace fan -} // namespace phosphor diff --git a/tach_sensor.hpp b/tach_sensor.hpp deleted file mode 100644 index 90d955b..0000000 --- a/tach_sensor.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include -#include -#include "sensor_base.hpp" - - -namespace phosphor -{ -namespace fan -{ -namespace presence -{ - -/** - * @class TachSensor - * @brief OpenBMC Tach feedback sensor presence implementation - * @details Derived sensor type that uses the tach feedback value to determine - * the presence of the fan enclosure that contains this sensor - */ -class TachSensor : public Sensor -{ - public: - TachSensor() = delete; - TachSensor(const TachSensor&) = delete; - TachSensor(TachSensor&&) = delete; - TachSensor& operator=(const TachSensor&) = delete; - TachSensor& operator=(TachSensor&&) = delete; - ~TachSensor() = default; - - /** - * @brief Constructs Tach Sensor Object - * - * @param[in] bus - Dbus bus object - * @param[in] id - ID name of this sensor - * @param[in] fanEnc - Reference to the fan enclosure with this sensor - */ - TachSensor( - sdbusplus::bus::bus& bus, - const std::string& id, - FanEnclosure& fanEnc) : - Sensor(id, fanEnc), - bus(bus), - tachSignal(bus, - match(id).c_str(), - handleTachChangeSignal, - this) - { - // Nothing to do here - } - - /** - * @brief Determine the presence of this sensor using the tach feedback - * - * @return Presence state based on tach feedback - */ - bool isPresent(); - - private: - /** @brief Connection for sdbusplus bus */ - sdbusplus::bus::bus& bus; - /** @brief Used to subscribe to dbus signals */ - sdbusplus::server::match::match tachSignal; - /** @brief Tach speed value given from the signal */ - int64_t tach = 0; - - /** - * @brief Appends the fan sensor id to construct a match string - * - * @param[in] id - Fan sensor id - * - * @return Match string to register signal for the fan sensor id - */ - static std::string match(const std::string& id) - { - return std::string("type='signal'," - "interface='org.freedesktop.DBus.Properties'," - "member='PropertiesChanged'," - "path='/xyz/openbmc_project/sensors/fan_tach/" + - id + "'"); - } - /** - * @brief Callback function on tach change signals - * - * @param[out] msg - Data associated with the subscribed signal - * @param[out] data - Pointer to this tach sensor object instance - * @param[out] err - Contains any sdbus error reference if occurred - * - * @return 0 - */ - static int handleTachChangeSignal(sd_bus_message* msg, - void* data, - sd_bus_error* err); - /** - * @brief Determine & handle when the signal was a tach change - * - * @param[in] msg - Expanded sdbusplus message data - * @param[in] err - Contains any sdbus error reference if occurred - */ - void handleTachChange(sdbusplus::message::message& msg, - sd_bus_error* err); - -}; - -} // namespace presence -} // namespace fan -} // namespace phosphor -- cgit v1.2.1