summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--sensorhandler.cpp117
-rw-r--r--sensorhandler.h19
-rw-r--r--types.hpp7
-rw-r--r--utils.cpp38
-rw-r--r--utils.hpp21
6 files changed, 197 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am
index 2b93ae5..53c21da 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,8 @@ libapphandler_la_SOURCES = \
transporthandler.cpp \
globalhandler.cpp \
groupext.cpp \
- sensor-gen.cpp
+ sensor-gen.cpp \
+ utils.cpp
libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) -version-info 0:0:0 -shared
libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS)
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index a40196c..53bb412 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -1,14 +1,19 @@
-#include "sensorhandler.h"
-#include "host-ipmid/ipmid-api.h"
#include <mapper.h>
#include <stdio.h>
#include <string.h>
-#include <stdint.h>
+#include <bitset>
#include <systemd/sd-bus.h>
+#include "host-ipmid/ipmid-api.h"
+#include <phosphor-logging/log.hpp>
#include "ipmid.hpp"
+#include "sensorhandler.h"
+#include "types.hpp"
+#include "utils.hpp"
extern int updateSensorRecordFromSSRAESC(const void *);
extern sd_bus *bus;
+extern const ipmi::sensor::IdInfoMap sensors;
+using namespace phosphor::logging;
void register_netfn_sen_functions() __attribute__((constructor));
@@ -343,22 +348,120 @@ ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
+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);
+
+ // Check if the Sensor Number is present
+ 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));
+
+ auto bus = sdbusplus::bus::new_default();
+ 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;
+}
ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
{
sensor_data_t *reqptr = (sensor_data_t*)request;
- ipmi_ret_t rc = IPMI_CC_OK;
printf("IPMI SET_SENSOR [0x%02x]\n",reqptr->sennum);
- updateSensorRecordFromSSRAESC(reqptr);
+ /*
+ * This would support the Set Sensor Reading command for the presence
+ * and functional state of Processor, Core & DIMM. For the remaining
+ * sensors the existing support is invoked.
+ */
+ auto ipmiRC = setSensorReading(request);
+
+ if(ipmiRC == IPMI_CC_SENSOR_INVALID)
+ {
+ updateSensorRecordFromSSRAESC(reqptr);
+ ipmiRC = IPMI_CC_OK;
+ }
*data_len=0;
-
- return rc;
+ return ipmiRC;
}
diff --git a/sensorhandler.h b/sensorhandler.h
index ca27b39..e908973 100644
--- a/sensorhandler.h
+++ b/sensorhandler.h
@@ -25,4 +25,23 @@ int set_sensor_dbus_state_s(uint8_t , const char *, const char *);
int set_sensor_dbus_state_y(uint8_t , const char *, const uint8_t);
int find_openbmc_path(const char *, const uint8_t , dbus_interface_t *);
+/**
+ * @struct SetSensorReadingReq
+ *
+ * IPMI Request data for Set Sensor Reading and Event Status Command
+ */
+struct SetSensorReadingReq
+{
+ uint8_t number;
+ uint8_t operation;
+ uint8_t reading;
+ uint8_t assertOffset0_7;
+ uint8_t assertOffset8_14;
+ uint8_t deassertOffset0_7;
+ uint8_t deassertOffset8_14;
+ uint8_t eventData1;
+ uint8_t eventData2;
+ uint8_t eventData3;
+} __attribute__((packed));
+
#endif
diff --git a/types.hpp b/types.hpp
index d8a1386..555dce3 100644
--- a/types.hpp
+++ b/types.hpp
@@ -44,5 +44,12 @@ struct Info
using Id = uint8_t;
using IdInfoMap = std::map<Id,Info>;
+using PropertyMap = std::map<DbusProperty, Value>;
+
+using InterfaceMap = std::map<DbusInterface, PropertyMap>;
+
+using Object = sdbusplus::message::object_path;
+using ObjectMap = std::map<Object, InterfaceMap>;
+
}//namespce sensor
}//namespace ipmi
diff --git a/utils.cpp b/utils.cpp
new file mode 100644
index 0000000..1823819
--- /dev/null
+++ b/utils.cpp
@@ -0,0 +1,38 @@
+#include "utils.hpp"
+
+namespace ipmi
+{
+
+std::string getService(sdbusplus::bus::bus& bus,
+ const std::string& intf,
+ const std::string& path)
+{
+ auto mapperCall = bus.new_method_call("xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/ObjectMapper",
+ "xyz.openbmc_project.ObjectMapper",
+ "GetObject");
+
+ mapperCall.append(path);
+ mapperCall.append(std::vector<std::string>({intf}));
+
+ auto mapperResponseMsg = bus.call(mapperCall);
+
+ if (mapperResponseMsg.is_method_error())
+ {
+ throw std::runtime_error("ERROR in mapper call");
+ }
+
+ std::map<std::string, std::vector<std::string>> mapperResponse;
+ mapperResponseMsg.read(mapperResponse);
+
+ if (mapperResponse.begin() == mapperResponse.end())
+ {
+ throw std::runtime_error("ERROR in reading the mapper response");
+ }
+
+ return mapperResponse.begin()->first;
+}
+
+} // namespace ipmi
+
+
diff --git a/utils.hpp b/utils.hpp
new file mode 100644
index 0000000..98be82a
--- /dev/null
+++ b/utils.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <sdbusplus/server.hpp>
+
+namespace ipmi
+{
+
+/**
+ * @brief Get the DBUS Service name for the input dbus path
+ *
+ * @param[in] bus - DBUS Bus Object
+ * @param[in] intf - DBUS Interface
+ * @param[in] path - DBUS Object Path
+ *
+ */
+std::string getService(sdbusplus::bus::bus& bus,
+ const std::string& intf,
+ const std::string& path);
+} // namespace ipmi
+
+
OpenPOWER on IntegriCloud