1 /*
2 // Copyright (c) 2019 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 "NVMeSensor.hpp"
18
19 #include "SensorPaths.hpp"
20 #include "Thresholds.hpp"
21 #include "Utils.hpp"
22 #include "sensor.hpp"
23
24 #include <boost/asio/io_context.hpp>
25 #include <sdbusplus/asio/connection.hpp>
26 #include <sdbusplus/asio/object_server.hpp>
27
28 #include <cstddef>
29 #include <cstdint>
30 #include <memory>
31 #include <stdexcept>
32 #include <string>
33 #include <utility>
34 #include <vector>
35
36 static constexpr double maxReading = 127;
37 static constexpr double minReading = 0;
38
NVMeSensor(sdbusplus::asio::object_server & objectServer,boost::asio::io_context &,std::shared_ptr<sdbusplus::asio::connection> & conn,const std::string & sensorName,std::vector<thresholds::Threshold> && thresholdsIn,const std::string & sensorConfiguration,const int busNumber,const uint8_t slaveAddr,bool smbusPEC)39 NVMeSensor::NVMeSensor(
40 sdbusplus::asio::object_server& objectServer,
41 boost::asio::io_context& /*unused*/,
42 std::shared_ptr<sdbusplus::asio::connection>& conn,
43 const std::string& sensorName,
44 std::vector<thresholds::Threshold>&& thresholdsIn,
45 const std::string& sensorConfiguration, const int busNumber,
46 const uint8_t slaveAddr, bool smbusPEC) :
47 Sensor(escapeName(sensorName), std::move(thresholdsIn), sensorConfiguration,
48 NVMeSensor::sensorType, false, false, maxReading, minReading, conn,
49 PowerState::on),
50 bus(busNumber), address(slaveAddr), smbusPEC(smbusPEC),
51 objServer(objectServer)
52 {
53 if (bus < 0)
54 {
55 throw std::invalid_argument("Invalid bus: Bus ID must not be negative");
56 }
57
58 sensorInterface = objectServer.add_interface(
59 "/xyz/openbmc_project/sensors/temperature/" + name,
60 "xyz.openbmc_project.Sensor.Value");
61
62 for (const auto& threshold : thresholds)
63 {
64 std::string interface = thresholds::getInterface(threshold.level);
65 thresholdInterfaces[static_cast<size_t>(threshold.level)] =
66 objectServer.add_interface(
67 "/xyz/openbmc_project/sensors/temperature/" + name, interface);
68 }
69 association = objectServer.add_interface(
70 "/xyz/openbmc_project/sensors/temperature/" + name,
71 association::interface);
72
73 setInitialProperties(sensor_paths::unitDegreesC);
74 // Mark as unavailable until the first packet has been received over NVMe
75 // MI.
76 markAvailable(false);
77 }
78
~NVMeSensor()79 NVMeSensor::~NVMeSensor()
80 {
81 // close the input dev to cancel async operations
82 for (const auto& iface : thresholdInterfaces)
83 {
84 objServer.remove_interface(iface);
85 }
86 objServer.remove_interface(sensorInterface);
87 objServer.remove_interface(association);
88 }
89
sample()90 bool NVMeSensor::sample()
91 {
92 if (inError())
93 {
94 if (scanDelay == 0)
95 {
96 scanDelay = scanDelayTicks;
97 }
98
99 scanDelay--;
100 }
101 else
102 {
103 scanDelay = 0;
104 }
105 return scanDelay == 0;
106 }
107
checkThresholds()108 void NVMeSensor::checkThresholds()
109 {
110 thresholds::checkThresholds(this);
111 }
112