summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rwxr-xr-xscripts/sensor-example.yaml44
-rw-r--r--scripts/writesensor.mako.cpp117
-rw-r--r--sensordatahandler.cpp258
-rw-r--r--sensordatahandler.hpp150
-rw-r--r--sensorhandler.cpp84
-rw-r--r--types.hpp7
7 files changed, 574 insertions, 89 deletions
diff --git a/Makefile.am b/Makefile.am
index 8dd3fc2..18b198c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -64,7 +64,8 @@ libapphandler_la_SOURCES = \
fru-read-gen.cpp \
selutility.cpp \
ipmi_fru_info_area.cpp \
- read_fru_data.cpp
+ read_fru_data.cpp \
+ sensordatahandler.cpp
libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS) -lstdc++fs -version-info 0:0:0 -shared
libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
diff --git a/scripts/sensor-example.yaml b/scripts/sensor-example.yaml
index c17b977..750da95 100755
--- a/scripts/sensor-example.yaml
+++ b/scripts/sensor-example.yaml
@@ -1,12 +1,35 @@
+#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
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.
+ readingType: assertion
+ #List of dbus interfaces associated with the interested properties.
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:
@@ -15,10 +38,25 @@
type: bool
assert: "true"
deassert: "false"
+0x07:
+ sensorType: 0xC3
+ path: /xyz/openbmc_project/control/host0
+ 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
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:
@@ -36,6 +74,9 @@
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:
@@ -53,6 +94,9 @@
sensorType: 0x0C
path: /system/chassis/motherboard/dimm3
sensorReadingType: 0x6F
+ serviceInterface: xyz.openbmc_project.Inventory.Manager
+ readingType: assertion
+ byteOffset: 0x00
interfaces:
xyz.openbmc_project.State.Decorator.OperationalStatus:
Functional:
diff --git a/scripts/writesensor.mako.cpp b/scripts/writesensor.mako.cpp
index cb3be09..41f9d60 100644
--- a/scripts/writesensor.mako.cpp
+++ b/scripts/writesensor.mako.cpp
@@ -2,10 +2,107 @@
## 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': '0',
+ 'eventdata1': 'cmdData.eventData1',
+ 'eventdata2': 'cmdData.eventData2',
+ 'eventdata3': 'cmdData.eventData3'}
+funcProps = {}
+%>\
+%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"
+ elif serviceInterface == "xyz.openbmc_project.Inventory.Manager":
+ command = "Notify"
+ else:
+ 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})
+%>\
+% endfor
+#include <bitset>
#include "types.hpp"
-using namespace ipmi::sensor;
+#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
+{
+
+
+namespace sensor_set
+{
+% for sensorType, funcProp in funcProps.iteritems():
+namespace sensor_type_${sensorType}
+{
+ipmi_ret_t update(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);
+}
+}//namespace sensor_type_${sensorType}
+
+% endfor
+}//namespace sensor_get
+}//namespace sensor
+}//namespace ipmi
+
+using namespace ipmi::sensor;
extern const IdInfoMap sensors = {
% for key in sensorDict.iterkeys():
% if key:
@@ -19,24 +116,30 @@ extern const IdInfoMap sensors = {
multiplier = sensor.get("multiplierM", 1)
offset = sensor.get("offsetB", 0)
exp = sensor.get("bExp", 0)
+ valueReadingType = sensor["readingType"]
+ updateFunc = funcProps[sensorType]["updateFunc"]
%>
${sensorType},"${path}",${readingType},${multiplier},${offset},${exp},
- ${offset * pow(10,exp)},{
+ ${offset * pow(10,exp)},${updateFunc},{
% for interface,properties in interfaces.iteritems():
{"${interface}",{
% for dbus_property,property_value in properties.iteritems():
{"${dbus_property}",{
% for offset,values in property_value.iteritems():
{ ${offset},{
- <% valueType = values["type"] %>\
- % for name,value in values.iteritems():
+ % if offset == 0xFF:
+ }},
+<% continue %>\
+ % endif
+<% valueType = values["type"] %>\
+ % for name,value in values.iteritems():
% if name == "type":
- <% continue %>\
+<% continue %>\
% endif
% if valueType == "string":
std::string("${value}"),
% elif valueType == "bool":
- <% value = str(value).lower() %>\
+<% value = str(value).lower() %>\
${value},
% else:
${value},
diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp
new file mode 100644
index 0000000..6c7b9ac
--- /dev/null
+++ b/sensordatahandler.cpp
@@ -0,0 +1,258 @@
+#include <bitset>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
+#include "types.hpp"
+#include "sensordatahandler.hpp"
+
+namespace ipmi
+{
+namespace sensor
+{
+
+using namespace phosphor::logging;
+using InternalFailure =
+ sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+
+static constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
+static constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
+static constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
+
+/** @brief get the D-Bus service and service path
+ * @param[in] bus - The Dbus bus object
+ * @param[in] interface - interface to the service
+ * @param[in] path - interested path in the list of objects
+ * @return pair of service path and service
+ */
+ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
+ const std::string& interface,
+ const std::string& path)
+{
+ auto depth = 0;
+ auto mapperCall = bus.new_method_call(MAPPER_BUSNAME,
+ MAPPER_PATH,
+ MAPPER_INTERFACE,
+ "GetSubTree");
+ mapperCall.append("/");
+ mapperCall.append(depth);
+ mapperCall.append(std::vector<Interface>({interface}));
+
+ auto mapperResponseMsg = bus.call(mapperCall);
+ if (mapperResponseMsg.is_method_error())
+ {
+ std::string err = "Error in mapper GetSubTree "
+ "Interface: " + interface;
+ log<level::ERR>(err.c_str());
+ elog<InternalFailure>();
+ }
+
+ MapperResponseType mapperResponse;
+ mapperResponseMsg.read(mapperResponse);
+ if (mapperResponse.empty())
+ {
+ std::string err = "Invalid response from mapper "
+ "Command: GetSubTree "
+ "Interface:" + interface;
+ log<level::ERR>(err.c_str());
+ elog<InternalFailure>();
+ }
+
+ if (path.empty())
+ {
+ //Get the first one if the path is not in list.
+ return std::make_pair(mapperResponse.begin()->first,
+ mapperResponse.begin()->second.begin()->first);
+ }
+ const auto& iter = mapperResponse.find(path);
+ if (iter == mapperResponse.end())
+ {
+ std::string err = "Error in finding sensor dbus"
+ "Command: GetSubTree "
+ "Interface:" + interface;
+ log<level::ERR>(err.c_str());
+ elog<InternalFailure>();
+ }
+ return std::make_pair(iter->first, iter->second.begin()->first);
+}
+
+AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData)
+{
+ Assertion assertionStates =
+ (static_cast<Assertion>(cmdData.assertOffset8_14)) << 8 |
+ cmdData.assertOffset0_7;
+ Deassertion deassertionStates =
+ (static_cast<Deassertion>(cmdData.deassertOffset8_14)) << 8 |
+ cmdData.deassertOffset0_7;
+ return std::make_pair(assertionStates, deassertionStates);
+}
+
+ipmi_ret_t updateToDbus(IpmiUpdateData& msg)
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ try
+ {
+ auto serviceResponseMsg = bus.call(msg);
+ if (serviceResponseMsg.is_method_error())
+ {
+ log<level::ERR>("Error in D-Bus call");
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ }
+ catch (InternalFailure& e)
+ {
+ commit<InternalFailure>();
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ return IPMI_CC_OK;
+}
+
+namespace set
+{
+
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+ const std::string& sensorPath,
+ const std::string& command,
+ const std::string& sensorInterface)
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ using namespace std::string_literals;
+
+ std::string dbusService;
+ std::string dbusPath;
+
+ std::tie(dbusPath, dbusService) = getServiceAndPath(bus,
+ sensorInterface,
+ sensorPath);
+ return bus.new_method_call(dbusService.c_str(),
+ dbusPath.c_str(),
+ updateInterface.c_str(),
+ command.c_str());
+}
+
+ipmi_ret_t appendDiscreteSignalData(IpmiUpdateData& msg,
+ const DbusInterfaceMap& interfaceMap,
+ uint8_t data)
+{
+ const auto& interface = interfaceMap.begin();
+ msg.append(interface->first);
+ for (const auto& property : interface->second)
+ {
+ msg.append(property.first);
+ const auto& iter = property.second.find(data);
+ if (iter == property.second.end())
+ {
+ log<level::ERR>("Invalid event data");
+ return IPMI_CC_PARM_OUT_OF_RANGE;
+ }
+ msg.append(iter->second.assert);
+ }
+ return IPMI_CC_OK;
+}
+
+ipmi_ret_t appendReadingData(IpmiUpdateData& msg,
+ const DbusInterfaceMap& interfaceMap,
+ const Value &data)
+{
+ 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;
+}
+
+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();
+ msg.append(interface->first);
+ for (const auto& property : interface->second)
+ {
+ msg.append(property.first);
+ for (const auto& value : property.second)
+ {
+ if (assertionSet.test(value.first))
+ {
+ msg.append(value.second.assert);
+ }
+ if (deassertionSet.test(value.first))
+ {
+ msg.append(value.second.deassert);
+ }
+ }
+ }
+ return IPMI_CC_OK;
+}
+}//namespace set
+
+namespace notify
+{
+
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+ const std::string& sensorPath,
+ const std::string& command,
+ const std::string& sensorInterface)
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ using namespace std::string_literals;
+
+ std::string dbusService;
+ std::string dbusPath;
+
+ std::tie(dbusPath, dbusService) = getServiceAndPath(bus,
+ updateInterface);
+
+ return bus.new_method_call(dbusService.c_str(),
+ dbusPath.c_str(),
+ updateInterface.c_str(),
+ command.c_str());
+}
+
+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);
+ ipmi::sensor::ObjectMap objects;
+ ipmi::sensor::InterfaceMap interfaces;
+ for (const auto& interface : interfaceMap)
+ {
+ for (const auto& property : interface.second)
+ {
+ ipmi::sensor::PropertyMap props;
+ bool valid = false;
+ for (const auto& value : property.second)
+ {
+ if (assertionSet.test(value.first))
+ {
+ props.emplace(property.first, value.second.assert);
+ valid = true;
+ }
+ else if (deassertionSet.test(value.first))
+ {
+ props.emplace(property.first, value.second.deassert);
+ valid = true;
+ }
+ }
+ if (valid)
+ {
+ interfaces.emplace(interface.first, std::move(props));
+ }
+ }
+ }
+ objects.emplace(sensorPath, std::move(interfaces));
+ msg.append(std::move(objects));
+ return IPMI_CC_OK;
+}
+}//namespace notify
+}//namespace sensor
+}//namespace ipmi
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
new file mode 100644
index 0000000..fa74235
--- /dev/null
+++ b/sensordatahandler.hpp
@@ -0,0 +1,150 @@
+#include "types.hpp"
+#include "host-ipmid/ipmid-api.h"
+
+namespace ipmi
+{
+namespace sensor
+{
+
+using Assertion = uint16_t;
+using Deassertion = uint16_t;
+using AssertionSet = std::pair<Assertion, Deassertion>;
+
+using Service = std::string;
+using Path = std::string;
+using Interface = std::string;
+
+using ServicePath = std::pair<Path, Service>;
+
+using Interfaces = std::vector<Interface>;
+
+using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
+
+/** @brief get the D-Bus service and service path
+ * @param[in] bus - The Dbus bus object
+ * @param[in] interface - interface to the service
+ * @param[in] path - interested path in the list of objects
+ * @return pair of service path and service
+ */
+ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
+ const std::string& interface,
+ const std::string& path = std::string());
+
+/** @brief Make assertion set from input data
+ * @param[in] cmdData - Input sensor data
+ * @return pair of assertion and deassertion set
+ */
+AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
+
+/** @brief send the message to DBus
+ * @param[in] msg - message to send
+ * @return failure status in IPMI error code
+ */
+ipmi_ret_t updateToDbus(const IpmiUpdateData& msg);
+
+namespace set
+{
+
+/** @brief Make a DBus message for a Dbus call
+ * @param[in] updateInterface - Interface name
+ * @param[in] sensorPath - Path of the sensor
+ * @param[in] command - command to be executed
+ * @param[in] sensorInterface - DBus interface of sensor
+ * @return a dbus message
+ */
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+ const std::string& sensorPath,
+ 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
+ * @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);
+
+/** @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
+ * @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
+ * @return a IPMI error code
+ */
+ipmi_ret_t appendReadingData(IpmiUpdateData& msg,
+ const DbusInterfaceMap& interfaceMap,
+ const Value& data);
+
+}//namespace set
+
+namespace notify
+{
+
+/** @brief Make a DBus message for a Dbus call
+ * @param[in] updateInterface - Interface name
+ * @param[in] sensorPath - Path of the sensor
+ * @param[in] command - command to be executed
+ * @param[in] sensorInterface - DBus interface of sensor
+ * @return a dbus message
+ */
+IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
+ const std::string& sensorPath,
+ const std::string& command,
+ const std::string& sensorInterface);
+
+/** @brief Create a message for IPMI discrete signal
+ * @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
+ */
+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);
+
+}//namespace notify
+}//namespace sensor
+}//namespace ipmi
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 25d6861..a4cfe34 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -408,93 +408,17 @@ ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_ret_t setSensorReading(void *request)
{
- auto cmdData = static_cast<SetSensorReadingReq *>(request);
-
- auto assertionStates =
- (static_cast<uint16_t>(cmdData->assertOffset8_14)) << 8 |
- cmdData->assertOffset0_7;
-
- auto deassertionStates =
- (static_cast<uint16_t>(cmdData->deassertOffset8_14)) << 8 |
- cmdData->deassertOffset0_7;
-
- std::bitset<16> assertionSet(assertionStates);
- std::bitset<16> deassertionSet(deassertionStates);
+ SetSensorReadingReq cmdData =
+ *(static_cast<SetSensorReadingReq *>(request));
// Check if the Sensor Number is present
- auto iter = sensors.find(cmdData->number);
+ const auto iter = sensors.find(cmdData.number);
if (iter == sensors.end())
{
return IPMI_CC_SENSOR_INVALID;
}
- auto& interfaceList = iter->second.sensorInterfaces;
- if (interfaceList.empty())
- {
- log<level::ERR>("Interface List empty for the sensor",
- entry("Sensor Number = %d", cmdData->number));
- return IPMI_CC_UNSPECIFIED_ERROR;
- }
-
- ipmi::sensor::ObjectMap objects;
- ipmi::sensor::InterfaceMap interfaces;
- for (const auto& interface : interfaceList)
- {
- for (const auto& property : interface.second)
- {
- ipmi::sensor::PropertyMap props;
- bool valid = false;
- for (const auto& value : property.second)
- {
- if (assertionSet.test(value.first))
- {
- props.emplace(property.first, value.second.assert);
- valid = true;
- }
- else if (deassertionSet.test(value.first))
- {
- props.emplace(property.first, value.second.deassert);
- valid = true;
- }
- }
- if (valid)
- {
- interfaces.emplace(interface.first, std::move(props));
- }
- }
- }
- objects.emplace(iter->second.sensorPath, std::move(interfaces));
-
- sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
- using namespace std::string_literals;
- static const auto intf = "xyz.openbmc_project.Inventory.Manager"s;
- static const auto path = "/xyz/openbmc_project/inventory"s;
- std::string service;
-
- try
- {
- service = ipmi::getService(bus, intf, path);
-
- // Update the inventory manager
- auto pimMsg = bus.new_method_call(service.c_str(),
- path.c_str(),
- intf.c_str(),
- "Notify");
- pimMsg.append(std::move(objects));
- auto inventoryMgrResponseMsg = bus.call(pimMsg);
- if (inventoryMgrResponseMsg.is_method_error())
- {
- log<level::ERR>("Error in notify call");
- return IPMI_CC_UNSPECIFIED_ERROR;
- }
- }
- catch (const std::runtime_error& e)
- {
- log<level::ERR>(e.what());
- return IPMI_CC_UNSPECIFIED_ERROR;
- }
-
- return IPMI_CC_OK;
+ return iter->second.updateFunc(cmdData, iter->second);
}
ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
diff --git a/types.hpp b/types.hpp
index d6fa988..801efd5 100644
--- a/types.hpp
+++ b/types.hpp
@@ -6,6 +6,7 @@
#include <string>
#include <sdbusplus/server.hpp>
+#include "sensorhandler.h"
namespace ipmi
{
@@ -15,7 +16,8 @@ using DbusService = std::string;
using DbusInterface = std::string;
using DbusObjectInfo = std::pair<DbusObjectPath, DbusService>;
using DbusProperty = std::string;
-using Value = sdbusplus::message::variant<bool, int64_t, uint8_t, std::string>;
+using Value = sdbusplus::message::variant<bool, int64_t, uint8_t,
+ std::string, uint32_t>;
using PropertyMap = std::map<DbusProperty, Value>;
using ObjectTree = std::map<DbusObjectPath,
std::map<DbusService, std::vector<DbusInterface>>>;
@@ -56,6 +58,7 @@ struct Info
OffsetB coefficientB;
Exponent exponentB;
ScaledOffset scaledOffset;
+ std::function<uint8_t(SetSensorReadingReq&,const Info&)> updateFunc;
DbusInterfaceMap sensorInterfaces;
};
@@ -69,6 +72,8 @@ using InterfaceMap = std::map<DbusInterface, PropertyMap>;
using Object = sdbusplus::message::object_path;
using ObjectMap = std::map<Object, InterfaceMap>;
+using IpmiUpdateData = sdbusplus::message::message;
+
struct SelData
{
Id sensorID;
OpenPOWER on IntegriCloud