blob: 0d96ce51630ea57e07e620824c687177a745cc5e [file] [log] [blame]
Brad Bishopdd62e362017-06-14 16:54:03 -04001/**
2 * Copyright © 2017 IBM 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#include <string>
17#include <tuple>
18#include <vector>
19#include "tach.hpp"
20#include "rpolicy.hpp"
21
22namespace phosphor
23{
24namespace fan
25{
26namespace presence
27{
28
29using namespace std::literals::string_literals;
30
31static const auto tachNamespace = "/xyz/openbmc_project/sensors/fan_tach/"s;
32static const auto tachIface = "xyz.openbmc_project.Sensor.Value"s;
33static const auto tachProperty = "Value"s;
34
35Tach::Tach(
36 const std::vector<std::string>& sensors) : currentState(false)
37{
38 // Initialize state.
39 for (const auto& s : sensors)
40 {
41 state.emplace_back(s, nullptr, 0);
42 }
43}
44
45bool Tach::start()
46{
47 for (size_t i = 0; i < state.size(); ++i)
48 {
49 auto& s = state[i];
50 auto tachPath = tachNamespace + std::get<std::string>(s);
51
52 // Register for signal callbacks.
53 std::get<1>(s) = std::make_unique<sdbusplus::bus::match::match>(
54 util::SDBusPlus::getBus(),
55 sdbusplus::bus::match::rules::propertiesChanged(
56 tachPath, tachIface),
57 [this, i](auto& msg){ this->propertiesChanged(i, msg);});
58
59 // Get an initial tach speed.
60 std::get<int64_t>(s) = util::SDBusPlus::getProperty<int64_t>(
61 tachPath,
62 tachIface,
63 tachProperty);
64 }
65
66 // Set the initial state of the sensor.
67 currentState = std::any_of(
68 state.begin(),
69 state.end(),
70 [](const auto & s)
71 {
72 return std::get<int64_t>(s) != 0;
73 });
74
75 return currentState;
76}
77
78void Tach::stop()
79{
80 for (auto& s : state)
81 {
82 // De-register signal callbacks.
83 std::get<1>(s) = nullptr;
84 }
85}
86
87bool Tach::present()
88{
89 // Live query the tach readings.
90 std::vector<int64_t> values;
91 for (const auto& s : state)
92 {
93 values.push_back(
94 util::SDBusPlus::getProperty<int64_t>(
95 tachNamespace + std::get<std::string>(s),
96 tachIface,
97 tachProperty));
98 }
99
100 return std::any_of(
101 values.begin(),
102 values.end(),
103 [](const auto & v) {return v != 0;});
104}
105
106void Tach::propertiesChanged(
107 size_t sensor,
108 sdbusplus::message::message& msg)
109{
110 std::string iface;
111 util::Properties<int64_t> properties;
112 msg.read(iface, properties);
113
114 propertiesChanged(sensor, properties);
115}
116
117void Tach::propertiesChanged(
118 size_t sensor,
119 const util::Properties<int64_t>& props)
120{
121 auto& s = state[sensor];
122
123 // Find the Value property containing the speed.
124 auto it = props.find(tachProperty);
125 if (it != props.end())
126 {
127 std::get<int64_t>(s) =
128 sdbusplus::message::variant_ns::get<int64_t>(it->second);
129
130 auto newState = std::any_of(
131 state.begin(),
132 state.end(),
133 [](const auto & s)
134 {
135 return std::get<int64_t>(s) != 0;
136 });
137
138 if (currentState != newState)
139 {
Brad Bishop11083ec2017-07-25 19:08:53 -0400140 getPolicy().stateChanged(newState, *this);
Brad Bishopdd62e362017-06-14 16:54:03 -0400141 currentState = newState;
142 }
143 }
144}
145
146} // namespace presence
147} // namespace fan
148} // namespace phosphor