xref: /openbmc/phosphor-pid-control/dbus/dbuspassive.cpp (revision da4a5dd133b88ebfeb69e89d05b381f81ba70e50)
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  #include "dbuspassive.hpp"
17  
18  #include "dbus/util.hpp"
19  
20  #include <chrono>
21  #include <cmath>
22  #include <memory>
23  #include <mutex>
24  #include <sdbusplus/bus.hpp>
25  #include <string>
26  
27  std::unique_ptr<ReadInterface> DbusPassive::CreateDbusPassive(
28      sdbusplus::bus::bus& bus, const std::string& type, const std::string& id,
29      DbusHelperInterface* helper)
30  {
31      if (helper == nullptr)
32      {
33          return nullptr;
34      }
35      if (!ValidType(type))
36      {
37          return nullptr;
38      }
39  
40      return std::make_unique<DbusPassive>(bus, type, id, helper);
41  }
42  
43  DbusPassive::DbusPassive(sdbusplus::bus::bus& bus, const std::string& type,
44                           const std::string& id, DbusHelperInterface* helper) :
45      ReadInterface(),
46      _bus(bus), _signal(bus, GetMatch(type, id).c_str(), DbusHandleSignal, this),
47      _id(id), _helper(helper)
48  {
49      /* Need to get the scale and initial value */
50      auto tempBus = sdbusplus::bus::new_default();
51      /* service == busname */
52      std::string path = GetSensorPath(type, id);
53      std::string service = _helper->GetService(tempBus, sensorintf, path);
54  
55      struct SensorProperties settings;
56      _helper->GetProperties(tempBus, service, path, &settings);
57  
58      _scale = settings.scale;
59      _value = settings.value * pow(10, _scale);
60      _updated = std::chrono::high_resolution_clock::now();
61  }
62  
63  ReadReturn DbusPassive::read(void)
64  {
65      std::lock_guard<std::mutex> guard(_lock);
66  
67      struct ReadReturn r = {_value, _updated};
68  
69      return r;
70  }
71  
72  void DbusPassive::setValue(double value)
73  {
74      std::lock_guard<std::mutex> guard(_lock);
75  
76      _value = value;
77      _updated = std::chrono::high_resolution_clock::now();
78  }
79  
80  int64_t DbusPassive::getScale(void)
81  {
82      return _scale;
83  }
84  
85  std::string DbusPassive::getId(void)
86  {
87      return _id;
88  }
89  
90  int HandleSensorValue(sdbusplus::message::message& msg, DbusPassive* owner)
91  {
92      std::string msgSensor;
93      std::map<std::string, sdbusplus::message::variant<int64_t, double>> msgData;
94  
95      msg.read(msgSensor, msgData);
96  
97      if (msgSensor == "xyz.openbmc_project.Sensor.Value")
98      {
99          auto valPropMap = msgData.find("Value");
100          if (valPropMap != msgData.end())
101          {
102              double value = mapbox::util::apply_visitor(VariantToDoubleVisitor(),
103                                                         valPropMap->second);
104  
105              value *= std::pow(10, owner->getScale());
106  
107              owner->setValue(value);
108          }
109      }
110  
111      return 0;
112  }
113  
114  int DbusHandleSignal(sd_bus_message* msg, void* usrData, sd_bus_error* err)
115  {
116      auto sdbpMsg = sdbusplus::message::message(msg);
117      DbusPassive* obj = static_cast<DbusPassive*>(usrData);
118  
119      return HandleSensorValue(sdbpMsg, obj);
120  }
121