diff options
author | Tom Joseph <tomjoseph@in.ibm.com> | 2017-03-09 12:34:35 +0530 |
---|---|---|
committer | Tom Joseph <tomjoseph@in.ibm.com> | 2017-03-15 16:14:58 +0530 |
commit | be703f71a3048c72ed567c397cd7caaf5f3d1bcf (patch) | |
tree | 407801458f8f36a03353564934ece9da909caa42 | |
parent | 28c2e7350a7d22a8314598101085b04f2b1ba274 (diff) | |
download | phosphor-host-ipmid-be703f71a3048c72ed567c397cd7caaf5f3d1bcf.tar.gz phosphor-host-ipmid-be703f71a3048c72ed567c397cd7caaf5f3d1bcf.zip |
Modify set sensor reading command
The Set Sensor handling code is modified to use generated code
for CPU, Core & DIMM sensors with Presence & Functional
offset.
Change-Id: I3b7fa4da870b745873da4732d457d793f5549ada
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | sensorhandler.cpp | 117 | ||||
-rw-r--r-- | sensorhandler.h | 19 | ||||
-rw-r--r-- | types.hpp | 7 | ||||
-rw-r--r-- | utils.cpp | 38 | ||||
-rw-r--r-- | utils.hpp | 21 |
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 @@ -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 + + |