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