1*2a40e939SJosh Lehan #include "ExternalSensor.hpp"
2*2a40e939SJosh Lehan 
3*2a40e939SJosh Lehan #include "SensorPaths.hpp"
4*2a40e939SJosh Lehan 
5*2a40e939SJosh Lehan #include <unistd.h>
6*2a40e939SJosh Lehan 
7*2a40e939SJosh Lehan #include <boost/algorithm/string/predicate.hpp>
8*2a40e939SJosh Lehan #include <boost/algorithm/string/replace.hpp>
9*2a40e939SJosh Lehan #include <boost/date_time/posix_time/posix_time.hpp>
10*2a40e939SJosh Lehan #include <sdbusplus/asio/connection.hpp>
11*2a40e939SJosh Lehan #include <sdbusplus/asio/object_server.hpp>
12*2a40e939SJosh Lehan 
13*2a40e939SJosh Lehan #include <iostream>
14*2a40e939SJosh Lehan #include <istream>
15*2a40e939SJosh Lehan #include <limits>
16*2a40e939SJosh Lehan #include <memory>
17*2a40e939SJosh Lehan #include <string>
18*2a40e939SJosh Lehan #include <vector>
19*2a40e939SJosh Lehan 
20*2a40e939SJosh Lehan ExternalSensor::ExternalSensor(
21*2a40e939SJosh Lehan     const std::string& objectType, sdbusplus::asio::object_server& objectServer,
22*2a40e939SJosh Lehan     std::shared_ptr<sdbusplus::asio::connection>& conn,
23*2a40e939SJosh Lehan     const std::string& sensorName, const std::string& sensorUnits,
24*2a40e939SJosh Lehan     std::vector<thresholds::Threshold>&& _thresholds,
25*2a40e939SJosh Lehan     const std::string& sensorConfiguration, const double& maxReading,
26*2a40e939SJosh Lehan     const double& minReading, const PowerState& powerState) :
27*2a40e939SJosh Lehan     // TODO(): When the Mutable feature is integrated,
28*2a40e939SJosh Lehan     // make sure all ExternalSensor instances are mutable,
29*2a40e939SJosh Lehan     // because that is the entire point of ExternalSensor,
30*2a40e939SJosh Lehan     // to accept sensor values written by an external source.
31*2a40e939SJosh Lehan     Sensor(boost::replace_all_copy(sensorName, " ", "_"),
32*2a40e939SJosh Lehan            std::move(_thresholds), sensorConfiguration, objectType, maxReading,
33*2a40e939SJosh Lehan            minReading, conn, powerState),
34*2a40e939SJosh Lehan     std::enable_shared_from_this<ExternalSensor>(), objServer(objectServer)
35*2a40e939SJosh Lehan {
36*2a40e939SJosh Lehan     // The caller must specify what physical characteristic
37*2a40e939SJosh Lehan     // an external sensor is expected to be measuring, such as temperature,
38*2a40e939SJosh Lehan     // as, unlike others, this is not implied by device type name.
39*2a40e939SJosh Lehan     std::string dbusPath = sensors::getPathForUnits(sensorUnits);
40*2a40e939SJosh Lehan     if (dbusPath.empty())
41*2a40e939SJosh Lehan     {
42*2a40e939SJosh Lehan         throw std::runtime_error("Units not in allow list");
43*2a40e939SJosh Lehan     }
44*2a40e939SJosh Lehan     std::string objectPath = sensors::objectPathPrefix;
45*2a40e939SJosh Lehan     objectPath += dbusPath;
46*2a40e939SJosh Lehan     objectPath += '/';
47*2a40e939SJosh Lehan     objectPath += sensorName;
48*2a40e939SJosh Lehan 
49*2a40e939SJosh Lehan     sensorInterface = objectServer.add_interface(
50*2a40e939SJosh Lehan         objectPath, "xyz.openbmc_project.Sensor.Value");
51*2a40e939SJosh Lehan 
52*2a40e939SJosh Lehan     if (thresholds::hasWarningInterface(thresholds))
53*2a40e939SJosh Lehan     {
54*2a40e939SJosh Lehan         thresholdInterfaceWarning = objectServer.add_interface(
55*2a40e939SJosh Lehan             objectPath, "xyz.openbmc_project.Sensor.Threshold.Warning");
56*2a40e939SJosh Lehan     }
57*2a40e939SJosh Lehan     if (thresholds::hasCriticalInterface(thresholds))
58*2a40e939SJosh Lehan     {
59*2a40e939SJosh Lehan         thresholdInterfaceCritical = objectServer.add_interface(
60*2a40e939SJosh Lehan             objectPath, "xyz.openbmc_project.Sensor.Threshold.Critical");
61*2a40e939SJosh Lehan     }
62*2a40e939SJosh Lehan 
63*2a40e939SJosh Lehan     association =
64*2a40e939SJosh Lehan         objectServer.add_interface(objectPath, association::interface);
65*2a40e939SJosh Lehan     setInitialProperties(conn);
66*2a40e939SJosh Lehan }
67*2a40e939SJosh Lehan 
68*2a40e939SJosh Lehan ExternalSensor::~ExternalSensor()
69*2a40e939SJosh Lehan {
70*2a40e939SJosh Lehan     objServer.remove_interface(association);
71*2a40e939SJosh Lehan     objServer.remove_interface(thresholdInterfaceCritical);
72*2a40e939SJosh Lehan     objServer.remove_interface(thresholdInterfaceWarning);
73*2a40e939SJosh Lehan     objServer.remove_interface(sensorInterface);
74*2a40e939SJosh Lehan }
75*2a40e939SJosh Lehan 
76*2a40e939SJosh Lehan void ExternalSensor::checkThresholds(void)
77*2a40e939SJosh Lehan {
78*2a40e939SJosh Lehan     thresholds::checkThresholds(this);
79*2a40e939SJosh Lehan }
80