xref: /openbmc/phosphor-pid-control/dbus/dbuswrite.cpp (revision bd63bcaca2ac9edf1778136cf240e3bbe8b31566)
1 /*
2 // Copyright (c) 2018 Intel 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 
17 #include "dbuswrite.hpp"
18 
19 #include "dbushelper_interface.hpp"
20 
21 #include <phosphor-logging/log.hpp>
22 #include <sdbusplus/bus.hpp>
23 
24 #include <exception>
25 #include <iostream>
26 #include <memory>
27 #include <string>
28 #include <variant>
29 
30 namespace pid_control
31 {
32 
33 constexpr const char* pwmInterface = "xyz.openbmc_project.Control.FanPwm";
34 
35 using namespace phosphor::logging;
36 
createDbusWrite(const std::string & path,int64_t min,int64_t max,std::unique_ptr<DbusHelperInterface> helper)37 std::unique_ptr<WriteInterface> DbusWritePercent::createDbusWrite(
38     const std::string& path, int64_t min, int64_t max,
39     std::unique_ptr<DbusHelperInterface> helper)
40 {
41     std::string connectionName;
42 
43     try
44     {
45         connectionName = helper->getService(pwmInterface, path);
46     }
47     catch (const std::exception& e)
48     {
49         return nullptr;
50     }
51 
52     return std::make_unique<DbusWritePercent>(path, min, max, connectionName);
53 }
54 
write(double value)55 void DbusWritePercent::write(double value)
56 {
57     return write(value, false, nullptr);
58 }
59 
write(double value,bool force,int64_t * written)60 void DbusWritePercent::write(double value, bool force, int64_t* written)
61 {
62     double minimum = getMin();
63     double maximum = getMax();
64 
65     double range = maximum - minimum;
66     double offset = range * value;
67     double ovalue = offset + minimum;
68 
69     if (oldValue == static_cast<int64_t>(ovalue))
70     {
71         if (!force)
72         {
73             if (written)
74             {
75                 *written = oldValue;
76             }
77             return;
78         }
79     }
80     auto writeBus = sdbusplus::bus::new_default();
81     auto mesg =
82         writeBus.new_method_call(connectionName.c_str(), path.c_str(),
83                                  "org.freedesktop.DBus.Properties", "Set");
84     mesg.append(pwmInterface, "Target",
85                 std::variant<uint64_t>(static_cast<uint64_t>(ovalue)));
86 
87     try
88     {
89         // TODO: if we don't use the reply, call_noreply()
90         auto resp = writeBus.call(mesg);
91     }
92     catch (const sdbusplus::exception_t& ex)
93     {
94         log<level::ERR>("Dbus Call Failure", entry("PATH=%s", path.c_str()),
95                         entry("WHAT=%s", ex.what()));
96     }
97 
98     oldValue = static_cast<int64_t>(ovalue);
99     if (written)
100     {
101         *written = oldValue;
102     }
103     return;
104 }
105 
createDbusWrite(const std::string & path,int64_t min,int64_t max,std::unique_ptr<DbusHelperInterface> helper)106 std::unique_ptr<WriteInterface> DbusWrite::createDbusWrite(
107     const std::string& path, int64_t min, int64_t max,
108     std::unique_ptr<DbusHelperInterface> helper)
109 {
110     std::string connectionName;
111 
112     try
113     {
114         connectionName = helper->getService(pwmInterface, path);
115     }
116     catch (const std::exception& e)
117     {
118         return nullptr;
119     }
120 
121     return std::make_unique<DbusWrite>(path, min, max, connectionName);
122 }
123 
write(double value)124 void DbusWrite::write(double value)
125 {
126     return write(value, false, nullptr);
127 }
128 
write(double value,bool force,int64_t * written)129 void DbusWrite::write(double value, bool force, int64_t* written)
130 {
131     if (oldValue == static_cast<int64_t>(value))
132     {
133         if (!force)
134         {
135             if (written)
136             {
137                 *written = oldValue;
138             }
139             return;
140         }
141     }
142     auto writeBus = sdbusplus::bus::new_default();
143     auto mesg =
144         writeBus.new_method_call(connectionName.c_str(), path.c_str(),
145                                  "org.freedesktop.DBus.Properties", "Set");
146     mesg.append(pwmInterface, "Target",
147                 std::variant<uint64_t>(static_cast<uint64_t>(value)));
148 
149     try
150     {
151         // TODO: consider call_noreplly
152         auto resp = writeBus.call(mesg);
153     }
154     catch (const sdbusplus::exception_t& ex)
155     {
156         log<level::ERR>("Dbus Call Failure", entry("PATH=%s", path.c_str()),
157                         entry("WHAT=%s", ex.what()));
158     }
159 
160     oldValue = static_cast<int64_t>(value);
161     if (written)
162     {
163         *written = oldValue;
164     }
165     return;
166 }
167 
168 } // namespace pid_control
169