| #pragma once |
| |
| #include "sensorhandler.h" |
| #include "types.hpp" |
| #include "utils.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(IpmiUpdateData& msg); |
| |
| namespace get |
| { |
| |
| /** |
| * @brief Helper function to map the dbus info to sensor's assertion status |
| * for the get sensor reading command. |
| * |
| * @param[in] sensorInfo - Dbus info related to sensor. |
| * @param[in] path - Dbus object path. |
| * @param[in] interface - Dbus interface. |
| * |
| * @return Response for get sensor reading command. |
| */ |
| GetSensorResponse mapDbusToAssertion(const Info& sensorInfo, |
| const InstancePath& path, |
| const DbusInterface& interface); |
| |
| /** |
| * @brief Map the Dbus info to sensor's assertion status in the Get sensor |
| * reading command response. |
| * |
| * @param[in] sensorInfo - Dbus info related to sensor. |
| * |
| * @return Response for get sensor reading command. |
| */ |
| GetSensorResponse assertion(const Info& sensorInfo); |
| |
| /** |
| * @brief Maps the Dbus info to the reading field in the Get sensor reading |
| * command response. |
| * |
| * @param[in] sensorInfo - Dbus info related to sensor. |
| * |
| * @return Response for get sensor reading command. |
| */ |
| GetSensorResponse eventdata2(const Info& sensorInfo); |
| |
| /** |
| * @brief readingAssertion is a case where the entire assertion state field |
| * serves as the sensor value. |
| * |
| * @tparam T - type of the dbus property related to sensor. |
| * @param[in] sensorInfo - Dbus info related to sensor. |
| * |
| * @return Response for get sensor reading command. |
| */ |
| template<typename T> |
| GetSensorResponse readingAssertion(const Info& sensorInfo) |
| { |
| sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; |
| GetSensorResponse response {}; |
| auto responseData = reinterpret_cast<GetReadingResponse*>(response.data()); |
| |
| auto service = ipmi::getService(bus, |
| sensorInfo.sensorInterface, |
| sensorInfo.sensorPath); |
| |
| auto propValue = ipmi::getDbusProperty( |
| bus, |
| service, |
| sensorInfo.sensorPath, |
| sensorInfo.propertyInterfaces.begin()->first, |
| sensorInfo.propertyInterfaces.begin()->second.begin()->first); |
| |
| setAssertionBytes(static_cast<uint16_t>(propValue.get<T>()), responseData); |
| |
| return response; |
| } |
| |
| /** @brief Map the Dbus info to the reading field in the Get sensor reading |
| * command response |
| * |
| * @tparam T - type of the dbus property related to sensor. |
| * @param[in] sensorInfo - Dbus info related to sensor. |
| * |
| * @return Response for get sensor reading command. |
| */ |
| template<typename T> |
| GetSensorResponse readingData(const Info& sensorInfo) |
| { |
| sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; |
| GetSensorResponse response {}; |
| auto responseData = reinterpret_cast<GetReadingResponse*>(response.data()); |
| |
| enableScanning(responseData); |
| |
| auto service = ipmi::getService(bus, |
| sensorInfo.sensorInterface, |
| sensorInfo.sensorPath); |
| |
| auto propValue = ipmi::getDbusProperty( |
| bus, |
| service, |
| sensorInfo.sensorPath, |
| sensorInfo.propertyInterfaces.begin()->first, |
| sensorInfo.propertyInterfaces.begin()->second.begin()->first); |
| |
| auto value = static_cast<uint8_t>( |
| (propValue.get<T>() - sensorInfo.scaledOffset) / |
| (sensorInfo.coefficientM ? sensorInfo.coefficientM : 1)); |
| |
| setReading(value, responseData); |
| |
| return response; |
| } |
| |
| } //namespace get |
| |
| 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 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 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 a discrete reading |
| * @param[in] cmdData - input sensor data |
| * @param[in] sensorInfo - sensor d-bus info |
| * @return an IPMI error code |
| */ |
| template<typename T> |
| ipmi_ret_t readingData(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); |
| |
| ipmi::sensor::Multiplier m = sensorInfo.coefficientM; |
| if (0 == m) |
| { |
| m = 1; // Avoid * 0 |
| } |
| |
| // TODO: Refactor this into a generated function depending on the type |
| // of conversion for the value between IPMI and dbus. |
| T raw_value = (m * cmdData.reading) + sensorInfo.scaledOffset; |
| |
| for (const auto& property : interface->second) |
| { |
| msg.append(property.first); |
| sdbusplus::message::variant<T> value = raw_value; |
| 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 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 |
| */ |
| 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 |
| */ |
| 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 |
| |
| 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 Update d-bus based on assertion type sensor data |
| * @param[in] interfaceMap - sensor interface |
| * @param[in] cmdData - input sensor data |
| * @param[in] sensorInfo - sensor d-bus info |
| * @return a IPMI error code |
| */ |
| ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, |
| const Info& sensorInfo); |
| |
| }//namespace notify |
| |
| namespace inventory |
| { |
| |
| namespace get |
| { |
| |
| /** |
| * @brief Map the Dbus info to sensor's assertion status in the Get sensor |
| * reading command response. |
| * |
| * @param[in] sensorInfo - Dbus info related to sensor. |
| * |
| * @return Response for get sensor reading command. |
| */ |
| GetSensorResponse assertion(const Info& sensorInfo); |
| |
| } // namespace get |
| |
| } // namespace inventory |
| }//namespace sensor |
| }//namespace ipmi |