blob: 65f651b2eec12d16cc95eeba4e39c2d954271168 [file] [log] [blame]
Willy Tude54f482021-01-26 15:59:09 -08001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
17#include "dbus-sdr/sdrutils.hpp"
18
Johnathan Mantey04b0b072023-10-10 12:30:35 -070019#include <nlohmann/json.hpp>
20
21#include <fstream>
Willy Tu4eca2512022-06-20 21:14:51 -070022#include <optional>
23#include <unordered_set>
24
Scron Chang2703b022021-07-06 15:47:45 +080025#ifdef FEATURE_HYBRID_SENSORS
26
27#include <ipmid/utils.hpp>
28namespace ipmi
29{
30namespace sensor
31{
32extern const IdInfoMap sensors;
33} // namespace sensor
34} // namespace ipmi
35
36#endif
37
Willy Tude54f482021-01-26 15:59:09 -080038namespace details
39{
Johnathan Mantey04b0b072023-10-10 12:30:35 -070040
41// IPMI supports a smaller number of sensors than are available via Redfish.
42// Trim the list of sensors, via a configuration file.
43// Read the IPMI Sensor Filtering section in docs/configuration.md for
44// a more detailed description.
45static void filterSensors(SensorSubTree& subtree)
46{
47 constexpr const char* filterFilename =
48 "/usr/share/ipmi-providers/sensor_filter.json";
49 std::ifstream filterFile(filterFilename);
50 if (!filterFile.good())
51 {
52 return;
53 }
54 nlohmann::json sensorFilterJSON = nlohmann::json::parse(filterFile, nullptr,
55 false);
56 nlohmann::json::iterator svcFilterit =
57 sensorFilterJSON.find("ServiceFilter");
58 if (svcFilterit == sensorFilterJSON.end())
59 {
60 return;
61 }
62
63 subtree.erase(std::remove_if(subtree.begin(), subtree.end(),
64 [svcFilterit](SensorSubTree::value_type& kv) {
65 auto& [_, serviceToIfaces] = kv;
66
67 for (auto service = svcFilterit->begin(); service != svcFilterit->end();
68 ++service)
69 {
70 serviceToIfaces.erase(*service);
71 }
72 return serviceToIfaces.empty();
73 }),
74 subtree.end());
75}
76
Kuiying Wanga8b5b262021-02-06 23:38:22 +080077uint16_t getSensorSubtree(std::shared_ptr<SensorSubTree>& subtree)
Willy Tude54f482021-01-26 15:59:09 -080078{
79 static std::shared_ptr<SensorSubTree> sensorTreePtr;
Kuiying Wanga8b5b262021-02-06 23:38:22 +080080 static uint16_t sensorUpdatedIndex = 0;
Willy Tude54f482021-01-26 15:59:09 -080081 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
Patrick Williams5d82f472022-07-22 19:26:53 -050082 static sdbusplus::bus::match_t sensorAdded(
Willy Tude54f482021-01-26 15:59:09 -080083 *dbus,
84 "type='signal',member='InterfacesAdded',arg0path='/xyz/openbmc_project/"
85 "sensors/'",
Patrick Williams5d82f472022-07-22 19:26:53 -050086 [](sdbusplus::message_t&) { sensorTreePtr.reset(); });
Willy Tude54f482021-01-26 15:59:09 -080087
Patrick Williams5d82f472022-07-22 19:26:53 -050088 static sdbusplus::bus::match_t sensorRemoved(
Willy Tude54f482021-01-26 15:59:09 -080089 *dbus,
90 "type='signal',member='InterfacesRemoved',arg0path='/xyz/"
91 "openbmc_project/sensors/'",
Patrick Williams5d82f472022-07-22 19:26:53 -050092 [](sdbusplus::message_t&) { sensorTreePtr.reset(); });
Willy Tude54f482021-01-26 15:59:09 -080093
Willy Tude54f482021-01-26 15:59:09 -080094 if (sensorTreePtr)
95 {
96 subtree = sensorTreePtr;
Kuiying Wanga8b5b262021-02-06 23:38:22 +080097 return sensorUpdatedIndex;
Willy Tude54f482021-01-26 15:59:09 -080098 }
99
100 sensorTreePtr = std::make_shared<SensorSubTree>();
101
Willy Tude54f482021-01-26 15:59:09 -0800102 static constexpr const int32_t depth = 2;
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800103
Patrick Williams369824e2023-10-20 11:18:23 -0500104 auto lbdUpdateSensorTree = [&dbus](const char* path,
105 const auto& interfaces) {
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800106 auto mapperCall = dbus->new_method_call(
107 "xyz.openbmc_project.ObjectMapper",
108 "/xyz/openbmc_project/object_mapper",
109 "xyz.openbmc_project.ObjectMapper", "GetSubTree");
110 SensorSubTree sensorTreePartial;
111
112 mapperCall.append(path, depth, interfaces);
113
114 try
115 {
116 auto mapperReply = dbus->call(mapperCall);
117 mapperReply.read(sensorTreePartial);
118 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500119 catch (const sdbusplus::exception_t& e)
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800120 {
121 phosphor::logging::log<phosphor::logging::level::ERR>(
122 "fail to update subtree",
123 phosphor::logging::entry("PATH=%s", path),
124 phosphor::logging::entry("WHAT=%s", e.what()));
125 return false;
126 }
127 if constexpr (debug)
128 {
129 std::fprintf(stderr, "IPMI updated: %zu sensors under %s\n",
130 sensorTreePartial.size(), path);
131 }
132 sensorTreePtr->merge(std::move(sensorTreePartial));
133 return true;
134 };
135
136 // Add sensors to SensorTree
137 static constexpr const std::array sensorInterfaces = {
Willy Tude54f482021-01-26 15:59:09 -0800138 "xyz.openbmc_project.Sensor.Value",
Jie Yangf0a89942021-07-29 15:30:25 -0700139 "xyz.openbmc_project.Sensor.ValueMutability",
Willy Tude54f482021-01-26 15:59:09 -0800140 "xyz.openbmc_project.Sensor.Threshold.Warning",
141 "xyz.openbmc_project.Sensor.Threshold.Critical"};
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800142 static constexpr const std::array vrInterfaces = {
143 "xyz.openbmc_project.Control.VoltageRegulatorMode"};
Willy Tude54f482021-01-26 15:59:09 -0800144
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500145 bool sensorRez = lbdUpdateSensorTree("/xyz/openbmc_project/sensors",
146 sensorInterfaces);
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800147
Scron Chang2703b022021-07-06 15:47:45 +0800148#ifdef FEATURE_HYBRID_SENSORS
149
150 if (!ipmi::sensor::sensors.empty())
151 {
152 for (const auto& sensor : ipmi::sensor::sensors)
153 {
154 // Threshold sensors should not be emplaced in here.
155 if (boost::starts_with(sensor.second.sensorPath,
156 "/xyz/openbmc_project/sensors/"))
157 {
158 continue;
159 }
160
161 // The bus service name is not listed in ipmi::sensor::Info. Give it
162 // an empty string. For those function using non-threshold sensors,
163 // the bus service name will be retrieved in an alternative way.
164 boost::container::flat_map<std::string, std::vector<std::string>>
165 connectionMap{
166 {"", {sensor.second.propertyInterfaces.begin()->first}}};
167 sensorTreePtr->emplace(sensor.second.sensorPath, connectionMap);
168 }
169 }
170
171#endif
172
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800173 // Error if searching for sensors failed.
174 if (!sensorRez)
Willy Tude54f482021-01-26 15:59:09 -0800175 {
Kuiying Wanga8b5b262021-02-06 23:38:22 +0800176 return sensorUpdatedIndex;
Willy Tude54f482021-01-26 15:59:09 -0800177 }
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800178
Johnathan Mantey04b0b072023-10-10 12:30:35 -0700179 filterSensors(*sensorTreePtr);
Hao Jiang9a5b51e2021-01-06 10:32:22 -0800180 // Add VR control as optional search path.
181 (void)lbdUpdateSensorTree("/xyz/openbmc_project/vr", vrInterfaces);
182
Willy Tude54f482021-01-26 15:59:09 -0800183 subtree = sensorTreePtr;
Kuiying Wanga8b5b262021-02-06 23:38:22 +0800184 sensorUpdatedIndex++;
Josh Lehana55c9532020-10-28 21:59:06 -0700185 // The SDR is being regenerated, wipe the old stats
186 sdrStatsTable.wipeTable();
Jie Yangf0a89942021-07-29 15:30:25 -0700187 sdrWriteTable.wipeTable();
Kuiying Wanga8b5b262021-02-06 23:38:22 +0800188 return sensorUpdatedIndex;
Willy Tude54f482021-01-26 15:59:09 -0800189}
190
191bool getSensorNumMap(std::shared_ptr<SensorNumMap>& sensorNumMap)
192{
193 static std::shared_ptr<SensorNumMap> sensorNumMapPtr;
194 bool sensorNumMapUpated = false;
Kuiying Wanga8b5b262021-02-06 23:38:22 +0800195 static uint16_t prevSensorUpdatedIndex = 0;
Willy Tude54f482021-01-26 15:59:09 -0800196 std::shared_ptr<SensorSubTree> sensorTree;
Kuiying Wanga8b5b262021-02-06 23:38:22 +0800197 uint16_t curSensorUpdatedIndex = details::getSensorSubtree(sensorTree);
Willy Tude54f482021-01-26 15:59:09 -0800198 if (!sensorTree)
199 {
200 return sensorNumMapUpated;
201 }
202
Kuiying Wanga8b5b262021-02-06 23:38:22 +0800203 if ((curSensorUpdatedIndex == prevSensorUpdatedIndex) && sensorNumMapPtr)
Willy Tude54f482021-01-26 15:59:09 -0800204 {
205 sensorNumMap = sensorNumMapPtr;
206 return sensorNumMapUpated;
207 }
Kuiying Wanga8b5b262021-02-06 23:38:22 +0800208 prevSensorUpdatedIndex = curSensorUpdatedIndex;
Willy Tude54f482021-01-26 15:59:09 -0800209
210 sensorNumMapPtr = std::make_shared<SensorNumMap>();
211
212 uint16_t sensorNum = 0;
213 uint16_t sensorIndex = 0;
214 for (const auto& sensor : *sensorTree)
215 {
216 sensorNumMapPtr->insert(
217 SensorNumMap::value_type(sensorNum, sensor.first));
218 sensorIndex++;
219 if (sensorIndex == maxSensorsPerLUN)
220 {
221 sensorIndex = lun1Sensor0;
222 }
223 else if (sensorIndex == (lun1Sensor0 | maxSensorsPerLUN))
224 {
225 // Skip assigning LUN 0x2 any sensors
226 sensorIndex = lun3Sensor0;
227 }
228 else if (sensorIndex == (lun3Sensor0 | maxSensorsPerLUN))
229 {
230 // this is an error, too many IPMI sensors
231 throw std::out_of_range("Maximum number of IPMI sensors exceeded.");
232 }
233 sensorNum = sensorIndex;
234 }
235 sensorNumMap = sensorNumMapPtr;
236 sensorNumMapUpated = true;
237 return sensorNumMapUpated;
238}
239} // namespace details
240
241bool getSensorSubtree(SensorSubTree& subtree)
242{
243 std::shared_ptr<SensorSubTree> sensorTree;
244 details::getSensorSubtree(sensorTree);
245 if (!sensorTree)
246 {
247 return false;
248 }
249
250 subtree = *sensorTree;
251 return true;
252}
253
Scron Chang2703b022021-07-06 15:47:45 +0800254#ifdef FEATURE_HYBRID_SENSORS
255// Static sensors are listed in sensor-gen.cpp.
256ipmi::sensor::IdInfoMap::const_iterator
257 findStaticSensor(const std::string& path)
258{
259 return std::find_if(
260 ipmi::sensor::sensors.begin(), ipmi::sensor::sensors.end(),
261 [&path](const ipmi::sensor::IdInfoMap::value_type& findSensor) {
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500262 return findSensor.second.sensorPath == path;
Patrick Williams369824e2023-10-20 11:18:23 -0500263 });
Scron Chang2703b022021-07-06 15:47:45 +0800264}
265#endif
266
Willy Tude54f482021-01-26 15:59:09 -0800267std::string getSensorTypeStringFromPath(const std::string& path)
268{
269 // get sensor type string from path, path is defined as
270 // /xyz/openbmc_project/sensors/<type>/label
271 size_t typeEnd = path.rfind("/");
272 if (typeEnd == std::string::npos)
273 {
274 return path;
275 }
276 size_t typeStart = path.rfind("/", typeEnd - 1);
277 if (typeStart == std::string::npos)
278 {
279 return path;
280 }
281 // Start at the character after the '/'
282 typeStart++;
283 return path.substr(typeStart, typeEnd - typeStart);
284}
285
286uint8_t getSensorTypeFromPath(const std::string& path)
287{
288 uint8_t sensorType = 0;
289 std::string type = getSensorTypeStringFromPath(path);
290 auto findSensor = sensorTypes.find(type.c_str());
291 if (findSensor != sensorTypes.end())
292 {
Scron Chang2b42d7e2021-07-06 15:45:47 +0800293 sensorType =
294 static_cast<uint8_t>(std::get<sensorTypeCodes>(findSensor->second));
Willy Tude54f482021-01-26 15:59:09 -0800295 } // else default 0x0 RESERVED
296
297 return sensorType;
298}
299
300uint16_t getSensorNumberFromPath(const std::string& path)
301{
302 std::shared_ptr<SensorNumMap> sensorNumMapPtr;
303 details::getSensorNumMap(sensorNumMapPtr);
304 if (!sensorNumMapPtr)
305 {
306 return invalidSensorNumber;
307 }
308
309 try
310 {
311 return sensorNumMapPtr->right.at(path);
312 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500313 catch (const std::out_of_range& e)
Willy Tude54f482021-01-26 15:59:09 -0800314 {
Willy Tude54f482021-01-26 15:59:09 -0800315 return invalidSensorNumber;
316 }
317}
318
319uint8_t getSensorEventTypeFromPath(const std::string& path)
320{
Scron Chang2b42d7e2021-07-06 15:45:47 +0800321 uint8_t sensorEventType = 0;
322 std::string type = getSensorTypeStringFromPath(path);
323 auto findSensor = sensorTypes.find(type.c_str());
324 if (findSensor != sensorTypes.end())
325 {
326 sensorEventType = static_cast<uint8_t>(
327 std::get<sensorEventTypeCodes>(findSensor->second));
328 }
329
330 return sensorEventType;
Willy Tude54f482021-01-26 15:59:09 -0800331}
332
333std::string getPathFromSensorNumber(uint16_t sensorNum)
334{
335 std::shared_ptr<SensorNumMap> sensorNumMapPtr;
336 details::getSensorNumMap(sensorNumMapPtr);
337 if (!sensorNumMapPtr)
338 {
339 return std::string();
340 }
341
342 try
343 {
344 return sensorNumMapPtr->left.at(sensorNum);
345 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500346 catch (const std::out_of_range& e)
Willy Tude54f482021-01-26 15:59:09 -0800347 {
Willy Tude54f482021-01-26 15:59:09 -0800348 return std::string();
349 }
350}
351
352namespace ipmi
353{
354
355std::map<std::string, std::vector<std::string>>
356 getObjectInterfaces(const char* path)
357{
358 std::map<std::string, std::vector<std::string>> interfacesResponse;
359 std::vector<std::string> interfaces;
360 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
361
Patrick Williams5d82f472022-07-22 19:26:53 -0500362 sdbusplus::message_t getObjectMessage =
Willy Tude54f482021-01-26 15:59:09 -0800363 dbus->new_method_call("xyz.openbmc_project.ObjectMapper",
364 "/xyz/openbmc_project/object_mapper",
365 "xyz.openbmc_project.ObjectMapper", "GetObject");
366 getObjectMessage.append(path, interfaces);
367
368 try
369 {
Patrick Williams5d82f472022-07-22 19:26:53 -0500370 sdbusplus::message_t response = dbus->call(getObjectMessage);
Willy Tude54f482021-01-26 15:59:09 -0800371 response.read(interfacesResponse);
372 }
373 catch (const std::exception& e)
374 {
375 phosphor::logging::log<phosphor::logging::level::ERR>(
376 "Failed to GetObject", phosphor::logging::entry("PATH=%s", path),
377 phosphor::logging::entry("WHAT=%s", e.what()));
378 }
379
380 return interfacesResponse;
381}
382
383std::map<std::string, Value> getEntityManagerProperties(const char* path,
384 const char* interface)
385{
386 std::map<std::string, Value> properties;
387 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
388
Patrick Williams5d82f472022-07-22 19:26:53 -0500389 sdbusplus::message_t getProperties =
Willy Tude54f482021-01-26 15:59:09 -0800390 dbus->new_method_call("xyz.openbmc_project.EntityManager", path,
391 "org.freedesktop.DBus.Properties", "GetAll");
392 getProperties.append(interface);
393
394 try
395 {
Patrick Williams5d82f472022-07-22 19:26:53 -0500396 sdbusplus::message_t response = dbus->call(getProperties);
Willy Tude54f482021-01-26 15:59:09 -0800397 response.read(properties);
398 }
399 catch (const std::exception& e)
400 {
401 phosphor::logging::log<phosphor::logging::level::ERR>(
402 "Failed to GetAll", phosphor::logging::entry("PATH=%s", path),
403 phosphor::logging::entry("INTF=%s", interface),
404 phosphor::logging::entry("WHAT=%s", e.what()));
405 }
406
407 return properties;
408}
409
Willy Tu4eca2512022-06-20 21:14:51 -0700410// Fetch the ipmiDecoratorPaths to get the list of dbus objects that
411// have ipmi decorator to prevent unnessary dbus call to fetch the info
412std::optional<std::unordered_set<std::string>>&
413 getIpmiDecoratorPaths(const std::optional<ipmi::Context::ptr>& ctx)
414{
415 static std::optional<std::unordered_set<std::string>> ipmiDecoratorPaths;
416
417 if (!ctx.has_value() || ipmiDecoratorPaths != std::nullopt)
418 {
419 return ipmiDecoratorPaths;
420 }
421
422 boost::system::error_code ec;
423 std::vector<std::string> paths =
424 (*ctx)->bus->yield_method_call<std::vector<std::string>>(
425 (*ctx)->yield, ec, "xyz.openbmc_project.ObjectMapper",
426 "/xyz/openbmc_project/object_mapper",
427 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
428 int32_t(0),
429 std::array<const char*, 1>{
430 "xyz.openbmc_project.Inventory.Decorator.Ipmi"});
431 if (ec)
432 {
433 return ipmiDecoratorPaths;
434 }
435
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500436 ipmiDecoratorPaths = std::unordered_set<std::string>(paths.begin(),
437 paths.end());
Willy Tu4eca2512022-06-20 21:14:51 -0700438 return ipmiDecoratorPaths;
439}
440
Willy Tude54f482021-01-26 15:59:09 -0800441const std::string* getSensorConfigurationInterface(
442 const std::map<std::string, std::vector<std::string>>&
443 sensorInterfacesResponse)
444{
445 auto entityManagerService =
446 sensorInterfacesResponse.find("xyz.openbmc_project.EntityManager");
447 if (entityManagerService == sensorInterfacesResponse.end())
448 {
449 return nullptr;
450 }
451
452 // Find the fan configuration first (fans can have multiple configuration
453 // interfaces).
454 for (const auto& entry : entityManagerService->second)
455 {
456 if (entry == "xyz.openbmc_project.Configuration.AspeedFan" ||
457 entry == "xyz.openbmc_project.Configuration.I2CFan" ||
458 entry == "xyz.openbmc_project.Configuration.NuvotonFan")
459 {
460 return &entry;
461 }
462 }
463
464 for (const auto& entry : entityManagerService->second)
465 {
466 if (boost::algorithm::starts_with(entry,
467 "xyz.openbmc_project.Configuration."))
468 {
469 return &entry;
470 }
471 }
472
473 return nullptr;
474}
475
476// Follow Association properties for Sensor back to the Board dbus object to
477// check for an EntityId and EntityInstance property.
Willy Tu4eca2512022-06-20 21:14:51 -0700478void updateIpmiFromAssociation(
479 const std::string& path,
480 const std::unordered_set<std::string>& ipmiDecoratorPaths,
481 const DbusInterfaceMap& sensorMap, uint8_t& entityId,
482 uint8_t& entityInstance)
Willy Tude54f482021-01-26 15:59:09 -0800483{
484 namespace fs = std::filesystem;
485
486 auto sensorAssociationObject =
487 sensorMap.find("xyz.openbmc_project.Association.Definitions");
488 if (sensorAssociationObject == sensorMap.end())
489 {
490 if constexpr (debug)
491 {
492 std::fprintf(stderr, "path=%s, no association interface found\n",
493 path.c_str());
494 }
495
496 return;
497 }
498
499 auto associationObject =
500 sensorAssociationObject->second.find("Associations");
501 if (associationObject == sensorAssociationObject->second.end())
502 {
503 if constexpr (debug)
504 {
505 std::fprintf(stderr, "path=%s, no association records found\n",
506 path.c_str());
507 }
508
509 return;
510 }
511
512 std::vector<Association> associationValues =
513 std::get<std::vector<Association>>(associationObject->second);
514
515 // loop through the Associations looking for the right one:
516 for (const auto& entry : associationValues)
517 {
518 // forward, reverse, endpoint
519 const std::string& forward = std::get<0>(entry);
520 const std::string& reverse = std::get<1>(entry);
521 const std::string& endpoint = std::get<2>(entry);
522
523 // We only currently concern ourselves with chassis+all_sensors.
524 if (!(forward == "chassis" && reverse == "all_sensors"))
525 {
526 continue;
527 }
528
529 // the endpoint is the board entry provided by
530 // Entity-Manager. so let's grab its properties if it has
531 // the right interface.
532
533 // just try grabbing the properties first.
Willy Tu4eca2512022-06-20 21:14:51 -0700534 ipmi::PropertyMap::iterator entityIdProp;
535 ipmi::PropertyMap::iterator entityInstanceProp;
536 if (ipmiDecoratorPaths.contains(endpoint))
537 {
538 std::map<std::string, Value> ipmiProperties =
539 getEntityManagerProperties(
540 endpoint.c_str(),
541 "xyz.openbmc_project.Inventory.Decorator.Ipmi");
Willy Tude54f482021-01-26 15:59:09 -0800542
Willy Tu4eca2512022-06-20 21:14:51 -0700543 entityIdProp = ipmiProperties.find("EntityId");
544 entityInstanceProp = ipmiProperties.find("EntityInstance");
545 if (entityIdProp != ipmiProperties.end())
546 {
547 entityId = static_cast<uint8_t>(
548 std::get<uint64_t>(entityIdProp->second));
549 }
550 if (entityInstanceProp != ipmiProperties.end())
551 {
552 entityInstance = static_cast<uint8_t>(
553 std::get<uint64_t>(entityInstanceProp->second));
554 }
Willy Tude54f482021-01-26 15:59:09 -0800555 }
556
557 // Now check the entity-manager entry for this sensor to see
558 // if it has its own value and use that instead.
559 //
560 // In theory, checking this first saves us from checking
561 // both, except in most use-cases identified, there won't be
562 // a per sensor override, so we need to always check both.
563 std::string sensorNameFromPath = fs::path(path).filename();
564
565 std::string sensorConfigPath = endpoint + "/" + sensorNameFromPath;
566
567 // Download the interfaces for the sensor from
568 // Entity-Manager to find the name of the configuration
569 // interface.
570 std::map<std::string, std::vector<std::string>>
571 sensorInterfacesResponse =
572 getObjectInterfaces(sensorConfigPath.c_str());
573
574 const std::string* configurationInterface =
575 getSensorConfigurationInterface(sensorInterfacesResponse);
576
Harvey Wu7bb84db2023-06-26 10:02:08 +0800577 // If there are multi association path settings and only one path exist,
578 // we need to continue if cannot find configuration interface for this
579 // sensor.
Willy Tude54f482021-01-26 15:59:09 -0800580 if (!configurationInterface)
581 {
Harvey Wu7bb84db2023-06-26 10:02:08 +0800582 continue;
Willy Tude54f482021-01-26 15:59:09 -0800583 }
584
585 // We found a configuration interface.
586 std::map<std::string, Value> configurationProperties =
587 getEntityManagerProperties(sensorConfigPath.c_str(),
588 configurationInterface->c_str());
589
590 entityIdProp = configurationProperties.find("EntityId");
591 entityInstanceProp = configurationProperties.find("EntityInstance");
592 if (entityIdProp != configurationProperties.end())
593 {
594 entityId =
595 static_cast<uint8_t>(std::get<uint64_t>(entityIdProp->second));
596 }
597 if (entityInstanceProp != configurationProperties.end())
598 {
599 entityInstance = static_cast<uint8_t>(
600 std::get<uint64_t>(entityInstanceProp->second));
601 }
602
603 // stop searching Association records.
604 break;
605 } // end for Association vectors.
606
607 if constexpr (debug)
608 {
609 std::fprintf(stderr, "path=%s, entityId=%d, entityInstance=%d\n",
610 path.c_str(), entityId, entityInstance);
611 }
612}
613
614} // namespace ipmi