xref: /openbmc/phosphor-pid-control/sensors/builder.cpp (revision da4a5dd133b88ebfeb69e89d05b381f81ba70e50)
1 /**
2  * Copyright 2017 Google Inc.
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 <iostream>
18 #include <map>
19 #include <string>
20 
21 /* Configuration. */
22 #include "conf.hpp"
23 #include "dbus/dbuspassive.hpp"
24 #include "dbus/dbuswrite.hpp"
25 #include "interfaces.hpp"
26 #include "notimpl/readonly.hpp"
27 #include "notimpl/writeonly.hpp"
28 #include "sensors/builder.hpp"
29 #include "sensors/host.hpp"
30 #include "sensors/manager.hpp"
31 #include "sensors/pluggable.hpp"
32 #include "sysfs/sysfsread.hpp"
33 #include "sysfs/sysfswrite.hpp"
34 #include "util.hpp"
35 
36 static constexpr bool deferSignals = true;
37 static DbusHelper helper;
38 
39 SensorManager BuildSensors(const std::map<std::string, struct sensor>& config)
40 {
41     SensorManager mgmr;
42     auto& HostSensorBus = mgmr.getHostBus();
43     auto& PassiveListeningBus = mgmr.getPassiveBus();
44 
45     for (auto& it : config)
46     {
47         std::unique_ptr<ReadInterface> ri;
48         std::unique_ptr<WriteInterface> wi;
49 
50         std::string name = it.first;
51         const struct sensor* info = &it.second;
52 
53         std::cerr << "Sensor: " << name << " " << info->type << " ";
54         std::cerr << info->readpath << " " << info->writepath << "\n";
55 
56         IOInterfaceType rtype = GetReadInterfaceType(info->readpath);
57         IOInterfaceType wtype = GetWriteInterfaceType(info->writepath);
58 
59         // fan sensors can be ready any way and written others.
60         // fan sensors are the only sensors this is designed to write.
61         // Nothing here should be write-only, although, in theory a fan could
62         // be. I'm just not sure how that would fit together.
63         // TODO(venture): It should check with the ObjectMapper to check if
64         // that sensor exists on the Dbus.
65         switch (rtype)
66         {
67             case IOInterfaceType::DBUSPASSIVE:
68                 ri = DbusPassive::CreateDbusPassive(PassiveListeningBus,
69                                                     info->type, name, &helper);
70                 /* TODO(venture): if this returns nullptr */
71                 break;
72             case IOInterfaceType::EXTERNAL:
73                 // These are a special case for read-only.
74                 break;
75             case IOInterfaceType::SYSFS:
76                 ri = std::make_unique<SysFsRead>(info->readpath);
77                 break;
78             default:
79                 ri = std::make_unique<WriteOnly>();
80                 break;
81         }
82 
83         if (info->type == "fan")
84         {
85             switch (wtype)
86             {
87                 case IOInterfaceType::SYSFS:
88                     if (info->max > 0)
89                     {
90                         wi = std::make_unique<SysFsWritePercent>(
91                             info->writepath, info->min, info->max);
92                     }
93                     else
94                     {
95                         wi = std::make_unique<SysFsWrite>(info->writepath,
96                                                           info->min, info->max);
97                     }
98 
99                     break;
100                 case IOInterfaceType::DBUSACTIVE:
101                     if (info->max > 0)
102                     {
103                         wi = std::make_unique<DbusWritePercent>(
104                             info->writepath, info->min, info->max, helper);
105                     }
106                     else
107                     {
108                         wi = std::make_unique<DbusWrite>(
109                             info->writepath, info->min, info->max, helper);
110                     }
111 
112                     break;
113                 default:
114                     wi = std::make_unique<ReadOnlyNoExcept>();
115                     break;
116             }
117 
118             auto sensor = std::make_unique<PluggableSensor>(
119                 name, info->timeout, std::move(ri), std::move(wi));
120             mgmr.addSensor(info->type, name, std::move(sensor));
121         }
122         else if (info->type == "temp" || info->type == "margin")
123         {
124             // These sensors are read-only, but only for this application
125             // which only writes to fan sensors.
126             std::cerr << info->type << " readpath: " << info->readpath << "\n";
127 
128             if (IOInterfaceType::EXTERNAL == rtype)
129             {
130                 std::cerr << "Creating HostSensor: " << name
131                           << " path: " << info->readpath << "\n";
132 
133                 /*
134                  * The reason we handle this as a HostSensor is because it's
135                  * not quite pluggable; but maybe it could be.
136                  */
137                 auto sensor = HostSensor::CreateTemp(
138                     name, info->timeout, HostSensorBus, info->readpath.c_str(),
139                     deferSignals);
140                 mgmr.addSensor(info->type, name, std::move(sensor));
141             }
142             else
143             {
144                 wi = std::make_unique<ReadOnlyNoExcept>();
145                 auto sensor = std::make_unique<PluggableSensor>(
146                     name, info->timeout, std::move(ri), std::move(wi));
147                 mgmr.addSensor(info->type, name, std::move(sensor));
148             }
149         }
150     }
151 
152     return mgmr;
153 }
154