diff options
-rwxr-xr-x | scripts/sensor-example.yaml | 154 | ||||
-rw-r--r-- | scripts/writesensor.mako.cpp | 127 | ||||
-rw-r--r-- | sensordatahandler.cpp | 63 | ||||
-rw-r--r-- | sensordatahandler.hpp | 133 | ||||
-rw-r--r-- | sensorhandler.cpp | 4 | ||||
-rw-r--r-- | types.hpp | 5 |
6 files changed, 213 insertions, 273 deletions
diff --git a/scripts/sensor-example.yaml b/scripts/sensor-example.yaml index 750da95..2556261 100755 --- a/scripts/sensor-example.yaml +++ b/scripts/sensor-example.yaml @@ -1,112 +1,76 @@ -#sample yaml with documentation -#Sensor Number -0xa6: - #Sensor Type - sensorType: 0x0C - #There are two types of updates one with Set method and other with - #Notify method for inventory updates. The path indicates Inventory path for - #the Notify method and Dbus object path for Set method. - path: /system/chassis/motherboard/dimm0 - #event reading type +# Sensor id is the key +0x60: + sensorType: 0x07 sensorReadingType: 0x6F - #Dbus service interface to make a bus call to update or request value of a - #property - serviceInterface: xyz.openbmc_project.Inventory.Manager - #command data has three fields, sensor reading value, assertion and - #deassertion bits and event data, this indicates which data field should - #be used. Possible value to be updated. + # A "set" operation on this sensor should update this d-bus path. + # If the path is not specified, an MRW parser will try to determine the path + # based on the sensor id, on MRW based systems. This typically happens for + # inventory items. + path: /org/open_power/control/occ0 + # The interface that exposes method(s) to update the path above. + serviceInterface: org.freedesktop.DBus.Properties + # Where the sensor value is represented - assertion bits/reading/event data readingType: assertion - #List of dbus interfaces associated with the interested properties. + eventType: 0x6F + # All the d-bus interfaces : properties that must be updated for this path interfaces: - #Dbus interface implementing the interested property. - xyz.openbmc_project.State.Decorator.OperationalStatus: - #DBus property - Functional: - #Offset, for assertion it should be a bit mask to indicate which bit - #indicates the property is true or false, in event or reading types - #the value will get mapped to a Dbus enum, 0xFF need to give if the - #reading or event value need to be updated as it is. - 0x04: - #type of the property - type: bool - #mapping from event offset bit in the command to the property value. - deassert: "true" - assert: "false" - xyz.openbmc_project.Inventory.Item: - Present: + # One or more interface dict entries + org.open_power.OCC.Status: + OccActive: + # Sensor type specific offset 0x06: - type: bool - assert: "true" - deassert: "false" -0x07: - sensorType: 0xC3 - path: /xyz/openbmc_project/control/host0 + # OccActive is a boolean + type: "bool" + # If offset 0x06 is asserted, set OccActive as false. + assert: "false" + deassert: "true" + +0x61: + sensorType: 0x04 sensorReadingType: 0x6F - serviceInterface: org.freedesktop.DBus.Properties - readingType: reading - interfaces: - xyz.openbmc_project.Control.Boot.RebootAttempts: - AttemptsLeft: - #A 0xFF indicates the value need to be send to dbus - 0xFF: - type: uint32_t -0xa8: - sensorType: 0x0C + # Inventory paths intentionally leave out the inventory root, + # /xyz/openbmc_project/inventory, because phosphor-inventory-manager + # adds that. path: /system/chassis/motherboard/dimm1 - sensorReadingType: 0x6F serviceInterface: xyz.openbmc_project.Inventory.Manager readingType: assertion - byteOffset: 0x00 interfaces: - xyz.openbmc_project.State.Decorator.OperationalStatus: - Functional: - 0x04: - type: bool - deassert: "true" - assert: "false" xyz.openbmc_project.Inventory.Item: Present: - 0x06: + 6: + assert: true + deassert: false type: bool - assert: "true" - deassert: "false" -0xaa: - sensorType: 0x0C - path: /system/chassis/motherboard/dimm2 - sensorReadingType: 0x6F - serviceInterface: xyz.openbmc_project.Inventory.Manager - readingType: assertion - byteOffset: 0x00 - interfaces: xyz.openbmc_project.State.Decorator.OperationalStatus: Functional: - 0x04: + 4: + assert: false + deassert: true type: bool - deassert: "true" - assert: "false" - xyz.openbmc_project.Inventory.Item: - Present: - 0x06: - type: bool - assert: "true" - deassert: "false" -0xac: - sensorType: 0x0C - path: /system/chassis/motherboard/dimm3 + +0x63: + interfaces: + xyz.openbmc_project.Control.Boot.RebootAttempts: + AttemptsLeft: + 0xFF: + type: uint32_t + path: /xyz/openbmc_project/state/host0 + # A special case of assertion, where the entire assert bitfield + # serves as the value, or reading. Hence, the offset above is intentionally + # 0xFF, to indicate not to check any specific bits in the assertion. + readingType: readingAssertion sensorReadingType: 0x6F - serviceInterface: xyz.openbmc_project.Inventory.Manager - readingType: assertion - byteOffset: 0x00 + sensorType: 0xC3 + serviceInterface: org.freedesktop.DBus.Properties + +0x62: interfaces: - xyz.openbmc_project.State.Decorator.OperationalStatus: - Functional: - 0x04: - type: bool - deassert: "true" - assert: "false" - xyz.openbmc_project.Inventory.Item: - Present: - 0x06: - type: bool - assert: "true" - deassert: "false" + xyz.openbmc_project.Control.Boot.RebootAttempts: + AttemptsLeft: + 0xFF: + type: uint32_t + path: /xyz/openbmc_project/state/host1 + readingType: readingAssertion + sensorReadingType: 0x6F + sensorType: 0xC3 + serviceInterface: org.freedesktop.DBus.Properties diff --git a/scripts/writesensor.mako.cpp b/scripts/writesensor.mako.cpp index 4355801..e4609ab 100644 --- a/scripts/writesensor.mako.cpp +++ b/scripts/writesensor.mako.cpp @@ -1,108 +1,56 @@ ## This file is a template. The comment below is emitted ## into the rendered file; feel free to edit this file. - // !!! WARNING: This is a GENERATED Code..Please do NOT Edit !!! <% -from collections import defaultdict -readingTypes = { 'reading': 'cmdData.reading', - 'assertion': '((cmdData.assertOffset8_14 << 8)|cmdData.assertOffset0_7)', - 'eventdata1': 'cmdData.eventData1', - 'eventdata2': 'cmdData.eventData2', - 'eventdata3': 'cmdData.eventData3'} -funcProps = {} +interfaceDict = {} %>\ %for key in sensorDict.iterkeys(): <% sensor = sensorDict[key] - sensorType = sensor["sensorType"] serviceInterface = sensor["serviceInterface"] - readingType = sensor["readingType"] if serviceInterface == "org.freedesktop.DBus.Properties": - command = "Set" + updateFunc = "set::" elif serviceInterface == "xyz.openbmc_project.Inventory.Manager": - command = "Notify" + updateFunc = "notify::" else: - assert "Un-supported interface: serviceInterface" + assert "Un-supported interface: " + serviceInterface endif - sensorInterface = serviceInterface - updateFunc = "sensor_set::sensor_type_" + str(sensorType) + "::update" - funcProps[sensorType] = {} - funcProps[sensorType].update({"command" : command}) - funcProps[sensorType].update({"path" : sensor["path"]}) - funcProps[sensorType].update({"serviceInterface" : serviceInterface}) - funcProps[sensorType].update({"updateFunc" : updateFunc}) - funcProps[sensorType].update({"readingType" : readingType}) - funcProps[sensorType].update({"source" : readingTypes[readingType]}) - funcProps[sensorType].update({"interfaces" : sensor["interfaces"]}) - if command == "Set": - for interface, props in funcProps[sensorType]["interfaces"].items(): - sensorInterface = interface - funcProps[sensorType].update({"sensorInterface" : sensorInterface}) + if serviceInterface not in interfaceDict: + interfaceDict[serviceInterface] = {} + interfaceDict[serviceInterface]["updateFunc"] = updateFunc %>\ % endfor -#include <bitset> + #include "types.hpp" -#include "host-ipmid/ipmid-api.h" -#include <phosphor-logging/elog-errors.hpp> -#include "xyz/openbmc_project/Common/error.hpp" -#include <phosphor-logging/log.hpp> #include "sensordatahandler.hpp" -namespace ipmi -{ -namespace sensor -{ - +using namespace ipmi::sensor; -namespace sensor_set -{ -% for sensorType, funcProp in funcProps.iteritems(): -namespace sensor_type_${sensorType} +%for key in sensorDict.iterkeys(): +<% + sensor = sensorDict[key] + readingType = sensor["readingType"] + interfaces = sensor["interfaces"] + for interface, properties in interfaces.items(): + for property, values in properties.items(): + for offset, attributes in values.items(): + type = attributes["type"] +%>\ +%if "readingAssertion" == readingType: +namespace sensor_${key} { -ipmi_ret_t update(const SetSensorReadingReq& cmdData, - const Info& sensorInfo) +inline ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData, + const Info& sensorInfo) { - auto msg = ${(funcProp["command"]).lower()}::makeDbusMsg( - "${funcProp['serviceInterface']}", - sensorInfo.sensorPath, - "${funcProp['command']}", - "${funcProp['sensorInterface']}"); - - auto interfaceList = sensorInfo.sensorInterfaces; -% for interface, properties in funcProp["interfaces"].iteritems(): - % for dbus_property, property_value in properties.iteritems(): - % for offset, values in property_value.iteritems(): - % if offset == 0xFF: -<% funcName = "appendReadingData"%>\ -<% param = "static_cast<"+values["type"]+">("+funcProp["source"]+")"%>\ - % elif funcProp["readingType"] == "assertion": -<% funcName = "appendAssertion"%>\ -<% param = "sensorInfo.sensorPath, cmdData"%>\ - % else: -<% funcName = "appendDiscreteSignalData"%>\ -<% param = funcProp["source"]%>\ - % endif - % endfor - % endfor -% endfor - auto result = ${(funcProp["command"]).lower()}::${funcName}(msg, - interfaceList, - ${param}); - if (result != IPMI_CC_OK) - { - return result; - } - return updateToDbus(msg); + return set::readingAssertion<${type}>(cmdData, sensorInfo); } -}//namespace sensor_type_${sensorType} +} // namespace sensor_${key} + +%endif % endfor -}//namespace sensor_get -}//namespace sensor -}//namespace ipmi -using namespace ipmi::sensor; extern const IdInfoMap sensors = { % for key in sensorDict.iterkeys(): % if key: @@ -111,28 +59,35 @@ extern const IdInfoMap sensors = { sensor = sensorDict[key] interfaces = sensor["interfaces"] path = sensor["path"] + serviceInterface = sensor["serviceInterface"] sensorType = sensor["sensorType"] readingType = sensor["sensorReadingType"] multiplier = sensor.get("multiplierM", 1) offset = sensor.get("offsetB", 0) exp = sensor.get("bExp", 0) valueReadingType = sensor["readingType"] - updateFunc = funcProps[sensorType]["updateFunc"] + updateFunc = interfaceDict[serviceInterface]["updateFunc"] + updateFunc += sensor["readingType"] + if "readingAssertion" == valueReadingType: + updateFunc = "sensor_" + str(key) + "::" + valueReadingType + sensorInterface = serviceInterface + if serviceInterface == "org.freedesktop.DBus.Properties": + sensorInterface = next(iter(interfaces)) %> - ${sensorType},"${path}",${readingType},${multiplier},${offset},${exp}, - ${offset * pow(10,exp)},${updateFunc},{ - % for interface,properties in interfaces.iteritems(): + ${sensorType},"${path}","${sensorInterface}",${readingType},${multiplier}, + ${offset},${exp},${offset * pow(10,exp)},${updateFunc},{ + % for interface,properties in interfaces.items(): {"${interface}",{ - % for dbus_property,property_value in properties.iteritems(): + % for dbus_property,property_value in properties.items(): {"${dbus_property}",{ - % for offset,values in property_value.iteritems(): + % for offset,values in property_value.items(): { ${offset},{ % if offset == 0xFF: }}, <% continue %>\ % endif <% valueType = values["type"] %>\ - % for name,value in values.iteritems(): + % for name,value in values.items(): % if name == "type": <% continue %>\ % endif diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp index 7c4cd3c..b9ef5e2 100644 --- a/sensordatahandler.cpp +++ b/sensordatahandler.cpp @@ -127,11 +127,17 @@ IpmiUpdateData makeDbusMsg(const std::string& updateInterface, command.c_str()); } -ipmi_ret_t appendDiscreteSignalData(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - uint8_t data) +ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, + const Info& sensorInfo, + uint8_t data) { - const auto& interface = interfaceMap.begin(); + auto msg = makeDbusMsg( + "org.freedesktop.DBus.Properties", + sensorInfo.sensorPath, + "Set", + sensorInfo.sensorInterface); + + const auto& interface = sensorInfo.propertyInterfaces.begin(); msg.append(interface->first); for (const auto& property : interface->second) { @@ -144,32 +150,22 @@ ipmi_ret_t appendDiscreteSignalData(IpmiUpdateData& msg, } msg.append(iter->second.assert); } - return IPMI_CC_OK; + return updateToDbus(msg); } -ipmi_ret_t appendReadingData(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - const Value &data) +ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, + const Info& sensorInfo) { - const auto& interface = interfaceMap.begin(); - msg.append(interface->first); - for (const auto& property : interface->second) - { - msg.append(property.first); - msg.append(data); - } - return IPMI_CC_OK; -} + auto msg = makeDbusMsg( + "org.freedesktop.DBus.Properties", + sensorInfo.sensorPath, + "Set", + sensorInfo.sensorInterface); -ipmi_ret_t appendAssertion(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - const std::string& sensorPath, - const SetSensorReadingReq& cmdData) -{ std::bitset<16> assertionSet(getAssertionSet(cmdData).first); std::bitset<16> deassertionSet(getAssertionSet(cmdData).second); - const auto& interface = interfaceMap.begin(); + const auto& interface = sensorInfo.propertyInterfaces.begin(); msg.append(interface->first); for (const auto& property : interface->second) { @@ -186,8 +182,9 @@ ipmi_ret_t appendAssertion(IpmiUpdateData& msg, } } } - return IPMI_CC_OK; + return updateToDbus(msg); } + }//namespace set namespace notify @@ -213,16 +210,20 @@ IpmiUpdateData makeDbusMsg(const std::string& updateInterface, command.c_str()); } -ipmi_ret_t appendAssertion(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - const std::string& sensorPath, - const SetSensorReadingReq& cmdData) +ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, + const Info& sensorInfo) { + auto msg = makeDbusMsg( + sensorInfo.sensorInterface, + sensorInfo.sensorPath, + "Notify", + sensorInfo.sensorInterface); + std::bitset<16> assertionSet(getAssertionSet(cmdData).first); std::bitset<16> deassertionSet(getAssertionSet(cmdData).second); ipmi::sensor::ObjectMap objects; ipmi::sensor::InterfaceMap interfaces; - for (const auto& interface : interfaceMap) + for (const auto& interface : sensorInfo.propertyInterfaces) { for (const auto& property : interface.second) { @@ -247,9 +248,9 @@ ipmi_ret_t appendAssertion(IpmiUpdateData& msg, } } } - objects.emplace(sensorPath, std::move(interfaces)); + objects.emplace(sensorInfo.sensorPath, std::move(interfaces)); msg.append(std::move(objects)); - return IPMI_CC_OK; + return updateToDbus(msg); } }//namespace notify }//namespace sensor diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp index f75c377..68a122d 100644 --- a/sensordatahandler.hpp +++ b/sensordatahandler.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "types.hpp" #include "host-ipmid/ipmid-api.h" @@ -57,37 +59,84 @@ IpmiUpdateData makeDbusMsg(const std::string& updateInterface, const std::string& command, const std::string& sensorInterface); -/** @brief Create a message for IPMI assertion - * @param[in] msg - Message to add the values - * @param[in] interface - sensor interface - * @param[in] sensorPath - Path of the sensor +/** @brief Update d-bus based on assertion type sensor data * @param[in] cmdData - input sensor data + * @param[in] sensorInfo - sensor d-bus info * @return a IPMI error code */ -ipmi_ret_t appendAssertion(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - const std::string& sensorPath, - const SetSensorReadingReq& cmdData); +ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, + const Info& sensorInfo); + +/** @brief Update d-bus based on a reading assertion + * @tparam T - type of d-bus property mapping this sensor + * @param[in] cmdData - input sensor data + * @param[in] sensorInfo - sensor d-bus info + * @return a IPMI error code + */ +template<typename T> +ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData, + const Info& sensorInfo) +{ + auto msg = makeDbusMsg( + "org.freedesktop.DBus.Properties", + sensorInfo.sensorPath, + "Set", + sensorInfo.sensorInterface); + + const auto& interface = sensorInfo.propertyInterfaces.begin(); + msg.append(interface->first); + for (const auto& property : interface->second) + { + msg.append(property.first); + sdbusplus::message::variant<T> value = + (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7; + msg.append(value); + } + return updateToDbus(msg); +} + + +/** @brief Update d-bus based on eventdata type sensor data + * @param[in] cmdData - input sensor data + * @param[in] sensorInfo - sensor d-bus info + * @return a IPMI error code + */ +ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, + const Info& sensorInfo, + uint8_t data); -/** @brief Create a message for discrete signal - * @param[in] msg - Message to add the values - * @param[in] interface - sensor interface - * @param[in] data - input discrete sensor data +/** @brief Update d-bus based on eventdata1 type sensor data + * @param[in] cmdData - input sensor data + * @param[in] sensorInfo - sensor d-bus info * @return a IPMI error code */ -ipmi_ret_t appendDiscreteSignalData(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - uint8_t data); - -/** @brief Create a message for reading data - * @param[in] msg - Message to add the values - * @param[in] interface - sensor interface - * @param[in] data - input sensor data +inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData, + const Info& sensorInfo) +{ + return eventdata(cmdData, sensorInfo, cmdData.eventData1); +} + +/** @brief Update d-bus based on eventdata2 type sensor data + * @param[in] cmdData - input sensor data + * @param[in] sensorInfo - sensor d-bus info * @return a IPMI error code */ -ipmi_ret_t appendReadingData(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - const Value& data); +inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData, + const Info& sensorInfo) +{ + return eventdata(cmdData, sensorInfo, cmdData.eventData2); +} + +/** @brief Update d-bus based on eventdata3 type sensor data + * @param[in] cmdData - input sensor data + * @param[in] sensorInfo - sensor d-bus info + * @return a IPMI error code + */ +inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData, + const Info& sensorInfo) +{ + return eventdata(cmdData, sensorInfo, cmdData.eventData3); +} }//namespace set @@ -106,44 +155,14 @@ IpmiUpdateData makeDbusMsg(const std::string& updateInterface, const std::string& command, const std::string& sensorInterface); -/** @brief Create a message for IPMI discrete signal - * @param[in] msg - Message to add the values +/** @brief Update d-bus based on assertion type sensor data * @param[in] interfaceMap - sensor interface - * @param[in] sensorPath - Path of the sensor * @param[in] cmdData - input sensor data + * @param[in] sensorInfo - sensor d-bus info * @return a IPMI error code */ -inline ipmi_ret_t appendDiscreteSignalData(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - uint8_t data) -{ - return IPMI_CC_OK; -} - -/** @brief Create a message for reading data - * @param[in] msg - Message to add the values - * @param[in] interfaceMap - sensor interface - * @param[in] data - input sensor data - * @return a IPMI error code - */ -inline ipmi_ret_t appendReadingData(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - const Value &data) -{ - return IPMI_CC_OK; -} - -/** @brief Create a message for IPMI asserting - * @param[in] msg - Message to add the values - * @param[in] interfaceMap - sensor interface - * @param[in] sensorPath - Path of the sensor - * @param[in] cmdData - input sensor data - * @return a IPMI error code - */ -ipmi_ret_t appendAssertion(IpmiUpdateData& msg, - const DbusInterfaceMap& interfaceMap, - const std::string& sensorPath, - const SetSensorReadingReq& cmdData); +ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, + const Info& sensorInfo); }//namespace notify }//namespace sensor diff --git a/sensorhandler.cpp b/sensorhandler.cpp index eac4215..d8cd0d4 100644 --- a/sensorhandler.cpp +++ b/sensorhandler.cpp @@ -206,7 +206,7 @@ int find_openbmc_path(uint8_t num, dbus_interface_t *interface) { // works for the Value interface but may not suffice for more complex // sensors. // tracked https://github.com/openbmc/phosphor-host-ipmid/issues/103 - strcpy(interface->interface, info.sensorInterfaces.begin()->first.c_str()); + strcpy(interface->interface, info.propertyInterfaces.begin()->first.c_str()); interface->sensornumber = num; final: @@ -649,7 +649,7 @@ ipmi_ret_t populate_record_from_dbus(get_sdr::SensorDataFullRecordBody *body, ipmi_data_len_t data_len) { /* Functional sensor case */ - if (info->sensorInterfaces.begin()->first == + if (info->propertyInterfaces.begin()->first == "xyz.openbmc_project.Sensor.Value") { // Get bus @@ -58,13 +58,14 @@ struct Info { Type sensorType; InstancePath sensorPath; + DbusInterface sensorInterface; ReadingType sensorReadingType; Multiplier coefficientM; OffsetB coefficientB; Exponent exponentB; ScaledOffset scaledOffset; - std::function<uint8_t(SetSensorReadingReq&,const Info&)> updateFunc; - DbusInterfaceMap sensorInterfaces; + std::function<uint8_t(SetSensorReadingReq&, const Info&)> updateFunc; + DbusInterfaceMap propertyInterfaces; }; using Id = uint8_t; |