sensor-cache: Use async calls in get sensor reading
Use the async calls in ipmiSensorGetSensorReading() for cached sensors.
Note that the code was using sdbusplus::message as the parameter for the
getFunc(), now it could be simplified to ipmi::PropertyMap and unify the
two cases: property update callback and getting property.
Tested: Verify the ipmi sensor list works fine.
Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: If7afed410f794a5317b8d4b4965cac291a735d12
diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp
index 97d11a7..62b58a1 100644
--- a/include/ipmid/types.hpp
+++ b/include/ipmid/types.hpp
@@ -175,8 +175,8 @@
#ifndef FEATURE_SENSORS_CACHE
std::function<GetSensorResponse(const Info&)> getFunc;
#else
- std::function<std::optional<GetSensorResponse>(
- uint8_t, const Info&, sdbusplus::message::message&)>
+ std::function<std::optional<GetSensorResponse>(uint8_t, const Info&,
+ const ipmi::PropertyMap&)>
getFunc;
#endif
Mutability mutability;
diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp
index d502268..949b732 100644
--- a/sensordatahandler.cpp
+++ b/sensordatahandler.cpp
@@ -205,21 +205,8 @@
}
#else
std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg)
+ const PropertyMap& /*properties*/)
{
- auto type = msg.get_type();
- if (type == msgTypeSignal)
- {
- // This is signal callback
- std::string interfaceName;
- msg.read(interfaceName);
- if (interfaceName != sensorInfo.sensorInterface)
- {
- // Not the interface we need
- return {};
- }
- }
-
// The assertion may contain multiple properties
// So we have to get the properties from DBus anyway
auto response = mapDbusToAssertion(sensorInfo, sensorInfo.sensorPath,
@@ -234,21 +221,8 @@
}
std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg)
+ const PropertyMap& /*properties*/)
{
- auto type = msg.get_type();
- if (type == msgTypeSignal)
- {
- // This is signal callback
- std::string interfaceName;
- msg.read(interfaceName);
- if (interfaceName != sensorInfo.sensorInterface)
- {
- // Not the interface we need
- return {};
- }
- }
-
// The eventdata2 may contain multiple properties
// So we have to get the properties from DBus anyway
auto response = mapDbusToEventdata2(sensorInfo);
@@ -476,21 +450,8 @@
#else
std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg)
+ const PropertyMap& /*properties*/)
{
- auto type = msg.get_type();
- if (type == msgTypeSignal)
- {
- // This is signal callback
- std::string interfaceName;
- msg.read(interfaceName);
- if (interfaceName != sensorInfo.sensorInterface)
- {
- // Not the interface we need
- return {};
- }
- }
-
// The assertion may contain multiple properties
// So we have to get the properties from DBus anyway
namespace fs = std::filesystem;
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
index 6768634..1cb2b40 100644
--- a/sensordatahandler.hpp
+++ b/sensordatahandler.hpp
@@ -30,16 +30,14 @@
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>>;
+using PropertyMap = ipmi::PropertyMap;
+
using namespace phosphor::logging;
/** @brief get the D-Bus service and service path
@@ -355,7 +353,7 @@
* @return Response for get sensor reading command.
*/
std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg);
+ const PropertyMap& properties);
/**
* @brief Maps the Dbus info to the reading field in the Get sensor reading
@@ -368,7 +366,7 @@
* @return Response for get sensor reading command.
*/
std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg);
+ const PropertyMap& properties);
/**
* @brief readingAssertion is a case where the entire assertion state field
@@ -382,30 +380,13 @@
* @return Response for get sensor reading command.
*/
template <typename T>
-std::optional<GetSensorResponse>
- readingAssertion(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg)
+std::optional<GetSensorResponse> readingAssertion(uint8_t id,
+ const Info& sensorInfo,
+ const PropertyMap& properties)
{
- auto type = msg.get_type();
- if (type == msgTypeSignal)
- {
- // This is signal callback
- std::string interfaceName;
- msg.read(interfaceName);
- if (interfaceName != sensorInfo.sensorInterface)
- {
- // Not the interface we need
- return {};
- }
- }
- // Now the message only contains the properties.
GetSensorResponse response{};
- std::map<std::string, ipmi::Value> properties;
-
enableScanning(&response);
- msg.read(properties);
-
auto iter = properties.find(
sensorInfo.propertyInterfaces.begin()->second.begin()->first);
if (iter == properties.end())
@@ -435,63 +416,33 @@
*/
template <typename T>
std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg)
+ const PropertyMap& properties)
{
- std::map<std::string, ipmi::Value> properties;
- auto type = msg.get_type();
- if (type == msgTypeSignal)
+ auto iter = properties.find("Functional");
+ if (iter != properties.end())
{
- // This is signal callback
- std::string interfaceName;
- msg.read(interfaceName);
-
- if (interfaceName ==
- "xyz.openbmc_project.State.Decorator.OperationalStatus")
- {
- msg.read(properties);
- auto val = properties.find("Functional");
- if (val != properties.end())
- {
- sensorCacheMap[id]->functional = std::get<bool>(val->second);
- }
- return {};
- }
- if (interfaceName == "xyz.openbmc_project.State.Decorator.Availability")
- {
- msg.read(properties);
- auto val = properties.find("Available");
- if (val != properties.end())
- {
- sensorCacheMap[id]->available = std::get<bool>(val->second);
- }
- return {};
- }
-
- if (interfaceName != sensorInfo.sensorInterface)
- {
- // Not the interface we need
- return {};
- }
-
-#ifdef UPDATE_FUNCTIONAL_ON_FAIL
- if (sensorCacheMap[id])
- {
- if (!sensorCacheMap[id]->functional)
- {
- throw SensorFunctionalError();
- }
- }
-#endif
+ sensorCacheMap[id]->functional = std::get<bool>(iter->second);
}
- // Now the message only contains the properties.
+ iter = properties.find("Available");
+ if (iter != properties.end())
+ {
+ sensorCacheMap[id]->available = std::get<bool>(iter->second);
+ }
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+ if (sensorCacheMap[id])
+ {
+ if (!sensorCacheMap[id]->functional)
+ {
+ throw SensorFunctionalError();
+ }
+ }
+#endif
GetSensorResponse response{};
enableScanning(&response);
- msg.read(properties);
-
- auto iter = properties.find(
+ iter = properties.find(
sensorInfo.propertyInterfaces.begin()->second.begin()->first);
if (iter == properties.end())
{
@@ -724,7 +675,7 @@
* @return Response for get sensor reading command.
*/
std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
- sdbusplus::message::message& msg);
+ const PropertyMap& properties);
#endif
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index b82e74b..6cc34f9 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -116,7 +116,12 @@
[&s](auto& msg) {
try
{
- s.second.getFunc(s.first, s.second, msg);
+ // This is signal callback
+ std::string interfaceName;
+ msg.read(interfaceName);
+ ipmi::PropertyMap props;
+ msg.read(props);
+ s.second.getFunc(s.first, s.second, props);
}
catch (const std::exception& e)
{
@@ -471,7 +476,7 @@
uint8_t, // threshold levels states
uint8_t // discrete reading sensor states
>
- ipmiSensorGetSensorReading(uint8_t sensorNum)
+ ipmiSensorGetSensorReading(ipmi::Context::ptr& ctx, uint8_t sensorNum)
{
if (sensorNum == 0xFF)
{
@@ -492,29 +497,29 @@
try
{
#ifdef FEATURE_SENSORS_CACHE
- // TODO
- const auto& sensorData = sensorCacheMap[sensorNum];
+ auto& sensorData = sensorCacheMap[sensorNum];
if (!sensorData.has_value())
{
// No cached value, try read it
- sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ std::string service;
+ boost::system::error_code ec;
const auto& sensorInfo = iter->second;
- auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
- sensorInfo.sensorPath);
- try
+ ec = ipmi::getService(ctx, sensorInfo.sensorInterface,
+ sensorInfo.sensorPath, service);
+ if (ec)
{
- auto method = bus.new_method_call(
- service.c_str(), sensorInfo.sensorPath.c_str(),
- "org.freedesktop.DBus.Properties", "GetAll");
- method.append(
- sensorInfo.propertyInterfaces.begin()->first.c_str());
- auto reply = bus.call(method);
- sensorInfo.getFunc(sensorNum, sensorInfo, reply);
+ return ipmi::responseUnspecifiedError();
}
- catch (const std::exception& e)
+
+ ipmi::PropertyMap props;
+ ec = ipmi::getAllDbusProperties(
+ ctx, service, sensorInfo.sensorPath,
+ sensorInfo.propertyInterfaces.begin()->first, props);
+ if (ec)
{
- fprintf(stderr, "Failed to get sensor %s\n",
- sensorInfo.sensorPath.c_str());
+ fprintf(stderr, "Failed to get sensor %s, %d: %s\n",
+ sensorInfo.sensorPath.c_str(), ec.value(),
+ ec.message().c_str());
// Intitilizing with default values
constexpr uint8_t senReading = 0;
constexpr uint5_t reserved{0};
@@ -529,6 +534,7 @@
assertionStatesLsb,
assertionStatesMsb);
}
+ sensorInfo.getFunc(sensorNum, sensorInfo, props);
}
return ipmi::responseSuccess(
sensorData->response.reading, uint5_t(0),