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