blob: 640c0ca2318f21e3da266b58b7df8ee842233c79 [file] [log] [blame]
Alexander Hansen46a755f2025-10-27 16:31:08 +01001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2017 Google Inc
Patrick Venture5e929092018-06-08 10:55:23 -07003
4#include <iostream>
Patrick Venturefe75b192018-06-08 11:19:43 -07005#include <map>
Patrick Venture8729eb92020-08-10 10:38:44 -07006#include <memory>
Patrick Venturefe75b192018-06-08 11:19:43 -07007#include <string>
Ed Tanousf8b6e552025-06-27 13:27:50 -07008#include <utility>
Patrick Venture5e929092018-06-08 10:55:23 -07009
10/* Configuration. */
11#include "conf.hpp"
Patrick Ventureaadb30d2020-08-10 09:17:11 -070012#include "dbus/dbushelper.hpp"
Patrick Venture5e929092018-06-08 10:55:23 -070013#include "dbus/dbuspassive.hpp"
James Feist7136a5a2018-07-19 09:52:05 -070014#include "dbus/dbuswrite.hpp"
Ed Tanousf8b6e552025-06-27 13:27:50 -070015#include "dbuspassiveredundancy.hpp"
Patrick Venturec404b3e2018-10-30 14:17:49 -070016#include "errors/exception.hpp"
Patrick Venture5e929092018-06-08 10:55:23 -070017#include "interfaces.hpp"
18#include "notimpl/readonly.hpp"
19#include "notimpl/writeonly.hpp"
Patrick Venturecdd61342020-08-07 15:49:56 -070020#include "sensors/build_utils.hpp"
Patrick Venture5e929092018-06-08 10:55:23 -070021#include "sensors/builder.hpp"
Patrick Venture5e929092018-06-08 10:55:23 -070022#include "sensors/host.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070023#include "sensors/manager.hpp"
Patrick Venture5e929092018-06-08 10:55:23 -070024#include "sensors/pluggable.hpp"
25#include "sysfs/sysfsread.hpp"
26#include "sysfs/sysfswrite.hpp"
Ed Tanousf8b6e552025-06-27 13:27:50 -070027
28#include <sdbusplus/bus.hpp>
Patrick Venture5e929092018-06-08 10:55:23 -070029
Patrick Venturea0764872020-08-08 07:48:43 -070030namespace pid_control
31{
32
Patrick Venture5e929092018-06-08 10:55:23 -070033static constexpr bool deferSignals = true;
34
Patrick Williams19300272025-02-01 08:22:48 -050035SensorManager buildSensors(
36 const std::map<std::string, conf::SensorConfig>& config,
37 sdbusplus::bus_t& passive, sdbusplus::bus_t& host)
Patrick Venture5e929092018-06-08 10:55:23 -070038{
Patrick Williamse3c60772025-04-07 17:53:42 -040039 SensorManager mgmr{passive, host};
Patrick Venturec179d402018-10-30 19:51:55 -070040 auto& hostSensorBus = mgmr.getHostBus();
41 auto& passiveListeningBus = mgmr.getPassiveBus();
Patrick Venture5e929092018-06-08 10:55:23 -070042
Patrick Venture4a2dc4d2018-10-23 09:02:55 -070043 for (const auto& it : config)
Patrick Venture5e929092018-06-08 10:55:23 -070044 {
45 std::unique_ptr<ReadInterface> ri;
46 std::unique_ptr<WriteInterface> wi;
47
48 std::string name = it.first;
Patrick Venture1df9e872020-10-08 15:35:01 -070049 const conf::SensorConfig* info = &it.second;
Patrick Venture5e929092018-06-08 10:55:23 -070050
51 std::cerr << "Sensor: " << name << " " << info->type << " ";
Patrick Venture69c51062019-02-11 09:46:03 -080052 std::cerr << info->readPath << " " << info->writePath << "\n";
Patrick Venture5e929092018-06-08 10:55:23 -070053
Patrick Venture69c51062019-02-11 09:46:03 -080054 IOInterfaceType rtype = getReadInterfaceType(info->readPath);
55 IOInterfaceType wtype = getWriteInterfaceType(info->writePath);
Patrick Venture5e929092018-06-08 10:55:23 -070056
57 // fan sensors can be ready any way and written others.
58 // fan sensors are the only sensors this is designed to write.
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070059 // Nothing here should be write-only, although, in theory a fan could
60 // be. I'm just not sure how that would fit together.
Patrick Venture5e929092018-06-08 10:55:23 -070061 // TODO(venture): It should check with the ObjectMapper to check if
62 // that sensor exists on the Dbus.
63 switch (rtype)
64 {
65 case IOInterfaceType::DBUSPASSIVE:
James Feist98b704e2019-06-03 16:24:53 -070066 // we only need to make one match based on the dbus object
67 static std::shared_ptr<DbusPassiveRedundancy> redundancy =
68 std::make_shared<DbusPassiveRedundancy>(
69 passiveListeningBus);
70
71 if (info->type == "fan")
72 {
73 ri = DbusPassive::createDbusPassive(
Patrick Venture8729eb92020-08-10 10:38:44 -070074 passiveListeningBus, info->type, name,
Patrick Williamscd1e78a2025-04-07 17:21:05 -040075 std::make_unique<DbusHelper>(passiveListeningBus), info,
76 redundancy);
James Feist98b704e2019-06-03 16:24:53 -070077 }
78 else
79 {
Patrick Venture8729eb92020-08-10 10:38:44 -070080 ri = DbusPassive::createDbusPassive(
81 passiveListeningBus, info->type, name,
Patrick Williamscd1e78a2025-04-07 17:21:05 -040082 std::make_unique<DbusHelper>(passiveListeningBus), info,
83 nullptr);
James Feist98b704e2019-06-03 16:24:53 -070084 }
Patrick Venturee7252862018-10-30 14:23:32 -070085 if (ri == nullptr)
86 {
87 throw SensorBuildException(
88 "Failed to create dbus passive sensor: " + name +
89 " of type: " + info->type);
90 }
Patrick Venture5e929092018-06-08 10:55:23 -070091 break;
92 case IOInterfaceType::EXTERNAL:
93 // These are a special case for read-only.
94 break;
95 case IOInterfaceType::SYSFS:
Patrick Venture69c51062019-02-11 09:46:03 -080096 ri = std::make_unique<SysFsRead>(info->readPath);
Patrick Venture5e929092018-06-08 10:55:23 -070097 break;
98 default:
99 ri = std::make_unique<WriteOnly>();
100 break;
101 }
102
103 if (info->type == "fan")
104 {
105 switch (wtype)
106 {
107 case IOInterfaceType::SYSFS:
108 if (info->max > 0)
109 {
110 wi = std::make_unique<SysFsWritePercent>(
Patrick Venture69c51062019-02-11 09:46:03 -0800111 info->writePath, info->min, info->max);
Patrick Venture5e929092018-06-08 10:55:23 -0700112 }
113 else
114 {
Patrick Venture69c51062019-02-11 09:46:03 -0800115 wi = std::make_unique<SysFsWrite>(info->writePath,
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700116 info->min, info->max);
Patrick Venture5e929092018-06-08 10:55:23 -0700117 }
118
119 break;
James Feist7136a5a2018-07-19 09:52:05 -0700120 case IOInterfaceType::DBUSACTIVE:
121 if (info->max > 0)
122 {
Patrick Venturef5e770b2018-10-30 12:28:53 -0700123 wi = DbusWritePercent::createDbusWrite(
Patrick Venture8729eb92020-08-10 10:38:44 -0700124 info->writePath, info->min, info->max,
Patrick Williamscd1e78a2025-04-07 17:21:05 -0400125 std::make_unique<DbusHelper>(passiveListeningBus));
James Feist7136a5a2018-07-19 09:52:05 -0700126 }
127 else
128 {
Patrick Venturef5e770b2018-10-30 12:28:53 -0700129 wi = DbusWrite::createDbusWrite(
Patrick Venture8729eb92020-08-10 10:38:44 -0700130 info->writePath, info->min, info->max,
Patrick Williamscd1e78a2025-04-07 17:21:05 -0400131 std::make_unique<DbusHelper>(passiveListeningBus));
Patrick Venturee7252862018-10-30 14:23:32 -0700132 }
133
134 if (wi == nullptr)
135 {
136 throw SensorBuildException(
137 "Unable to create write dbus interface for path: " +
Patrick Venture69c51062019-02-11 09:46:03 -0800138 info->writePath);
James Feist7136a5a2018-07-19 09:52:05 -0700139 }
140
141 break;
Patrick Venture5e929092018-06-08 10:55:23 -0700142 default:
143 wi = std::make_unique<ReadOnlyNoExcept>();
144 break;
145 }
146
147 auto sensor = std::make_unique<PluggableSensor>(
Potin Laie1fa8592025-08-29 15:27:08 +0800148 name, info->timeout, std::move(ri), std::move(wi),
149 info->ignoreFailIfHostOff);
Patrick Venturefe75b192018-06-08 11:19:43 -0700150 mgmr.addSensor(info->type, name, std::move(sensor));
Patrick Venture5e929092018-06-08 10:55:23 -0700151 }
Josh Lehan23e22b92022-11-12 22:37:58 -0800152 else if (info->type == "temp" || info->type == "margin" ||
153 info->type == "power" || info->type == "powersum")
Patrick Venture5e929092018-06-08 10:55:23 -0700154 {
155 // These sensors are read-only, but only for this application
156 // which only writes to fan sensors.
Patrick Venture69c51062019-02-11 09:46:03 -0800157 std::cerr << info->type << " readPath: " << info->readPath << "\n";
Patrick Venture5e929092018-06-08 10:55:23 -0700158
159 if (IOInterfaceType::EXTERNAL == rtype)
160 {
161 std::cerr << "Creating HostSensor: " << name
Patrick Venture69c51062019-02-11 09:46:03 -0800162 << " path: " << info->readPath << "\n";
Patrick Venture5e929092018-06-08 10:55:23 -0700163
164 /*
165 * The reason we handle this as a HostSensor is because it's
166 * not quite pluggable; but maybe it could be.
167 */
Patrick Venture563a3562018-10-30 09:31:26 -0700168 auto sensor = HostSensor::createTemp(
Patrick Venture69c51062019-02-11 09:46:03 -0800169 name, info->timeout, hostSensorBus, info->readPath.c_str(),
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700170 deferSignals);
Patrick Venturefe75b192018-06-08 11:19:43 -0700171 mgmr.addSensor(info->type, name, std::move(sensor));
Patrick Venture5e929092018-06-08 10:55:23 -0700172 }
173 else
174 {
175 wi = std::make_unique<ReadOnlyNoExcept>();
176 auto sensor = std::make_unique<PluggableSensor>(
Potin Laie1fa8592025-08-29 15:27:08 +0800177 name, info->timeout, std::move(ri), std::move(wi),
178 info->ignoreFailIfHostOff);
Patrick Venturefe75b192018-06-08 11:19:43 -0700179 mgmr.addSensor(info->type, name, std::move(sensor));
Patrick Venture5e929092018-06-08 10:55:23 -0700180 }
181 }
182 }
183
184 return mgmr;
185}
Patrick Venturea0764872020-08-08 07:48:43 -0700186
187} // namespace pid_control