17136a5aeSJames Feist /*
27136a5aeSJames Feist // Copyright (c) 2018 Intel Corporation
37136a5aeSJames Feist //
47136a5aeSJames Feist // Licensed under the Apache License, Version 2.0 (the "License");
57136a5aeSJames Feist // you may not use this file except in compliance with the License.
67136a5aeSJames Feist // You may obtain a copy of the License at
77136a5aeSJames Feist //
87136a5aeSJames Feist // http://www.apache.org/licenses/LICENSE-2.0
97136a5aeSJames Feist //
107136a5aeSJames Feist // Unless required by applicable law or agreed to in writing, software
117136a5aeSJames Feist // distributed under the License is distributed on an "AS IS" BASIS,
127136a5aeSJames Feist // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137136a5aeSJames Feist // See the License for the specific language governing permissions and
147136a5aeSJames Feist // limitations under the License.
157136a5aeSJames Feist */
167136a5aeSJames Feist
17aadb30ddSPatrick Venture #include "dbuswrite.hpp"
18aadb30ddSPatrick Venture
19aadb30ddSPatrick Venture #include "dbushelper_interface.hpp"
20da4a5dd1SPatrick Venture
2176ce5d77SPatrick Venture #include <phosphor-logging/log.hpp>
227136a5aeSJames Feist #include <sdbusplus/bus.hpp>
23a83a3eccSPatrick Venture
248729eb98SPatrick Venture #include <exception>
25a83a3eccSPatrick Venture #include <iostream>
26a83a3eccSPatrick Venture #include <memory>
27f5e770b3SPatrick Venture #include <string>
281f802f5eSJames Feist #include <variant>
29f5e770b3SPatrick Venture
30a076487aSPatrick Venture namespace pid_control
31a076487aSPatrick Venture {
32a076487aSPatrick Venture
33f5e770b3SPatrick Venture constexpr const char* pwmInterface = "xyz.openbmc_project.Control.FanPwm";
347136a5aeSJames Feist
3576ce5d77SPatrick Venture using namespace phosphor::logging;
3676ce5d77SPatrick Venture
createDbusWrite(const std::string & path,int64_t min,int64_t max,std::unique_ptr<DbusHelperInterface> helper)378729eb98SPatrick Venture std::unique_ptr<WriteInterface> DbusWritePercent::createDbusWrite(
388729eb98SPatrick Venture const std::string& path, int64_t min, int64_t max,
398729eb98SPatrick Venture std::unique_ptr<DbusHelperInterface> helper)
40f5e770b3SPatrick Venture {
41f5e770b3SPatrick Venture std::string connectionName;
42f5e770b3SPatrick Venture
43f5e770b3SPatrick Venture try
44f5e770b3SPatrick Venture {
459b93692dSPatrick Venture connectionName = helper->getService(pwmInterface, path);
46f5e770b3SPatrick Venture }
47f5e770b3SPatrick Venture catch (const std::exception& e)
48f5e770b3SPatrick Venture {
49f5e770b3SPatrick Venture return nullptr;
50f5e770b3SPatrick Venture }
51f5e770b3SPatrick Venture
52f5e770b3SPatrick Venture return std::make_unique<DbusWritePercent>(path, min, max, connectionName);
53f5e770b3SPatrick Venture }
54f5e770b3SPatrick Venture
write(double value)557136a5aeSJames Feist void DbusWritePercent::write(double value)
567136a5aeSJames Feist {
572400ce43SJosh Lehan return write(value, false, nullptr);
582400ce43SJosh Lehan }
592400ce43SJosh Lehan
write(double value,bool force,int64_t * written)602400ce43SJosh Lehan void DbusWritePercent::write(double value, bool force, int64_t* written)
612400ce43SJosh Lehan {
625f59c0fdSPatrick Venture double minimum = getMin();
635f59c0fdSPatrick Venture double maximum = getMax();
647136a5aeSJames Feist
655f59c0fdSPatrick Venture double range = maximum - minimum;
665f59c0fdSPatrick Venture double offset = range * value;
675f59c0fdSPatrick Venture double ovalue = offset + minimum;
68cd9e109fSJames Feist
69cd9e109fSJames Feist if (oldValue == static_cast<int64_t>(ovalue))
70cd9e109fSJames Feist {
712400ce43SJosh Lehan if (!force)
722400ce43SJosh Lehan {
732400ce43SJosh Lehan if (written)
742400ce43SJosh Lehan {
752400ce43SJosh Lehan *written = oldValue;
762400ce43SJosh Lehan }
77cd9e109fSJames Feist return;
78cd9e109fSJames Feist }
792400ce43SJosh Lehan }
8080b5d9a8SJames Feist auto writeBus = sdbusplus::bus::new_default();
81*bd63bcacSPatrick Williams auto mesg =
82*bd63bcacSPatrick Williams writeBus.new_method_call(connectionName.c_str(), path.c_str(),
83*bd63bcacSPatrick Williams "org.freedesktop.DBus.Properties", "Set");
8477ac8566SAndrew Geissler mesg.append(pwmInterface, "Target",
8577ac8566SAndrew Geissler std::variant<uint64_t>(static_cast<uint64_t>(ovalue)));
8676ce5d77SPatrick Venture
8776ce5d77SPatrick Venture try
887136a5aeSJames Feist {
8976ce5d77SPatrick Venture // TODO: if we don't use the reply, call_noreply()
9080b5d9a8SJames Feist auto resp = writeBus.call(mesg);
917136a5aeSJames Feist }
92b228bc30SPatrick Williams catch (const sdbusplus::exception_t& ex)
9376ce5d77SPatrick Venture {
9476ce5d77SPatrick Venture log<level::ERR>("Dbus Call Failure", entry("PATH=%s", path.c_str()),
9576ce5d77SPatrick Venture entry("WHAT=%s", ex.what()));
9676ce5d77SPatrick Venture }
9776ce5d77SPatrick Venture
98cd9e109fSJames Feist oldValue = static_cast<int64_t>(ovalue);
992400ce43SJosh Lehan if (written)
1002400ce43SJosh Lehan {
1012400ce43SJosh Lehan *written = oldValue;
1022400ce43SJosh Lehan }
1037136a5aeSJames Feist return;
1047136a5aeSJames Feist }
1057136a5aeSJames Feist
createDbusWrite(const std::string & path,int64_t min,int64_t max,std::unique_ptr<DbusHelperInterface> helper)106*bd63bcacSPatrick Williams std::unique_ptr<WriteInterface> DbusWrite::createDbusWrite(
107*bd63bcacSPatrick Williams const std::string& path, int64_t min, int64_t max,
1088729eb98SPatrick Venture std::unique_ptr<DbusHelperInterface> helper)
109f5e770b3SPatrick Venture {
110f5e770b3SPatrick Venture std::string connectionName;
111f5e770b3SPatrick Venture
112f5e770b3SPatrick Venture try
113f5e770b3SPatrick Venture {
1149b93692dSPatrick Venture connectionName = helper->getService(pwmInterface, path);
115f5e770b3SPatrick Venture }
116f5e770b3SPatrick Venture catch (const std::exception& e)
117f5e770b3SPatrick Venture {
118f5e770b3SPatrick Venture return nullptr;
119f5e770b3SPatrick Venture }
120f5e770b3SPatrick Venture
121f5e770b3SPatrick Venture return std::make_unique<DbusWrite>(path, min, max, connectionName);
122f5e770b3SPatrick Venture }
123f5e770b3SPatrick Venture
write(double value)1247136a5aeSJames Feist void DbusWrite::write(double value)
1257136a5aeSJames Feist {
1262400ce43SJosh Lehan return write(value, false, nullptr);
1272400ce43SJosh Lehan }
1282400ce43SJosh Lehan
write(double value,bool force,int64_t * written)1292400ce43SJosh Lehan void DbusWrite::write(double value, bool force, int64_t* written)
1302400ce43SJosh Lehan {
131cd9e109fSJames Feist if (oldValue == static_cast<int64_t>(value))
132cd9e109fSJames Feist {
1332400ce43SJosh Lehan if (!force)
1342400ce43SJosh Lehan {
1352400ce43SJosh Lehan if (written)
1362400ce43SJosh Lehan {
1372400ce43SJosh Lehan *written = oldValue;
1382400ce43SJosh Lehan }
139cd9e109fSJames Feist return;
140cd9e109fSJames Feist }
1412400ce43SJosh Lehan }
14280b5d9a8SJames Feist auto writeBus = sdbusplus::bus::new_default();
143*bd63bcacSPatrick Williams auto mesg =
144*bd63bcacSPatrick Williams writeBus.new_method_call(connectionName.c_str(), path.c_str(),
145*bd63bcacSPatrick Williams "org.freedesktop.DBus.Properties", "Set");
14677ac8566SAndrew Geissler mesg.append(pwmInterface, "Target",
14777ac8566SAndrew Geissler std::variant<uint64_t>(static_cast<uint64_t>(value)));
14876ce5d77SPatrick Venture
14976ce5d77SPatrick Venture try
1507136a5aeSJames Feist {
15176ce5d77SPatrick Venture // TODO: consider call_noreplly
15280b5d9a8SJames Feist auto resp = writeBus.call(mesg);
1537136a5aeSJames Feist }
154b228bc30SPatrick Williams catch (const sdbusplus::exception_t& ex)
15576ce5d77SPatrick Venture {
15676ce5d77SPatrick Venture log<level::ERR>("Dbus Call Failure", entry("PATH=%s", path.c_str()),
15776ce5d77SPatrick Venture entry("WHAT=%s", ex.what()));
15876ce5d77SPatrick Venture }
15976ce5d77SPatrick Venture
160cd9e109fSJames Feist oldValue = static_cast<int64_t>(value);
1612400ce43SJosh Lehan if (written)
1622400ce43SJosh Lehan {
1632400ce43SJosh Lehan *written = oldValue;
1642400ce43SJosh Lehan }
1657136a5aeSJames Feist return;
1667136a5aeSJames Feist }
167a076487aSPatrick Venture
168a076487aSPatrick Venture } // namespace pid_control
169