blob: 3103ff5f36288f48c94366e7d74c7b72b71c2bd5 [file] [log] [blame]
Qiang XUe28d1fa2019-02-27 13:50:56 +08001/*
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
Andrew Jefferye73bd0a2023-01-25 10:39:57 +103017#include "ChassisIntrusionSensor.hpp"
18
Qiang XUe28d1fa2019-02-27 13:50:56 +080019#include <fcntl.h>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070020#include <linux/i2c.h>
Qiang XUe28d1fa2019-02-27 13:50:56 +080021#include <sys/ioctl.h>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070022#include <sys/syslog.h>
Matt Simmering79a160b2022-11-14 16:50:48 -080023#include <systemd/sd-journal.h>
Qiang XUe28d1fa2019-02-27 13:50:56 +080024#include <unistd.h>
25
Chau Lycebb28c2022-10-21 10:01:52 +000026#include <Utils.hpp>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070027#include <boost/asio/error.hpp>
Ed Tanous1f978632023-02-28 18:16:39 -080028#include <boost/asio/io_context.hpp>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070029#include <boost/asio/posix/stream_descriptor.hpp>
30#include <gpiod.hpp>
George Liue9a1c9c2025-02-20 15:02:35 +080031#include <phosphor-logging/lg2.hpp>
James Feist38fb5982020-05-28 10:09:54 -070032#include <sdbusplus/asio/object_server.hpp>
33
Qiang XUe28d1fa2019-02-27 13:50:56 +080034#include <chrono>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070035#include <cstddef>
36#include <cstdint>
37#include <filesystem>
Chau Lycebb28c2022-10-21 10:01:52 +000038#include <fstream>
Qiang XUe28d1fa2019-02-27 13:50:56 +080039#include <iostream>
Patrick Venture96e97db2019-10-31 13:44:38 -070040#include <memory>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070041#include <stdexcept>
Qiang XUe28d1fa2019-02-27 13:50:56 +080042#include <string>
Ed Tanous8a57ec02020-10-09 12:46:52 -070043#include <utility>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070044#include <vector>
Qiang XUe28d1fa2019-02-27 13:50:56 +080045
James Feist38fb5982020-05-28 10:09:54 -070046extern "C"
47{
Qiang XUe28d1fa2019-02-27 13:50:56 +080048#include <i2c/smbus.h>
49#include <linux/i2c-dev.h>
50}
51
Chau Lycebb28c2022-10-21 10:01:52 +000052static constexpr unsigned int defaultPollSec = 1;
53static constexpr unsigned int sensorFailedPollSec = 5;
54static unsigned int intrusionSensorPollSec = defaultPollSec;
Chau Lyb318dca2022-10-26 04:12:52 +000055static constexpr const char* hwIntrusionValStr =
56 "xyz.openbmc_project.Chassis.Intrusion.Status.HardwareIntrusion";
57static constexpr const char* normalValStr =
58 "xyz.openbmc_project.Chassis.Intrusion.Status.Normal";
59static constexpr const char* manualRearmStr =
60 "xyz.openbmc_project.Chassis.Intrusion.RearmMode.Manual";
61static constexpr const char* autoRearmStr =
62 "xyz.openbmc_project.Chassis.Intrusion.RearmMode.Automatic";
Qiang XUe28d1fa2019-02-27 13:50:56 +080063
64// SMLink Status Register
65const static constexpr size_t pchStatusRegIntrusion = 0x04;
66
67// Status bit field masks
68const static constexpr size_t pchRegMaskIntrusion = 0x01;
69
Chau Ly95f49932023-04-19 09:44:55 +000070// Value to clear intrusion status hwmon file
71const static constexpr size_t intrusionStatusHwmonClearValue = 0;
72
Chau Lycebb28c2022-10-21 10:01:52 +000073void ChassisIntrusionSensor::updateValue(const size_t& value)
Qiang XUe28d1fa2019-02-27 13:50:56 +080074{
Chau Lycebb28c2022-10-21 10:01:52 +000075 std::string newValue = value != 0 ? hwIntrusionValStr : normalValStr;
76
Chau Lyb318dca2022-10-26 04:12:52 +000077 // Take no action if the hardware status does not change
Josh Lehan833661a2020-03-04 17:35:41 -080078 // Same semantics as Sensor::updateValue(const double&)
79 if (newValue == mValue)
80 {
81 return;
82 }
83
Alexander Hansen89be6142025-09-18 15:36:16 +020084 lg2::debug("Update value from '{VALUE}' to '{NEWVALUE}'", "VALUE", mValue,
85 "NEWVALUE", newValue);
Chau Lycebb28c2022-10-21 10:01:52 +000086
Chau Lyb318dca2022-10-26 04:12:52 +000087 // Automatic Rearm mode allows direct update
88 // Manual Rearm mode requires a rearm action to clear the intrusion
89 // status
90 if (!mAutoRearm)
91 {
92 if (newValue == normalValStr)
93 {
94 // Chassis is first closed from being open. If it has been
95 // rearmed externally, reset the flag, update mValue and
96 // return, without having to write "Normal" to DBus property
97 // (because the rearm action already did).
98 // Otherwise, return with no more action.
99 if (mRearmFlag)
100 {
101 mRearmFlag = false;
102 mValue = newValue;
103 }
104 return;
105 }
106 }
107
108 // Flush the rearm flag everytime it allows an update to Dbus
109 mRearmFlag = false;
110
Qiang XUe28d1fa2019-02-27 13:50:56 +0800111 // indicate that it is internal set call
Chau Lyb318dca2022-10-26 04:12:52 +0000112 mOverridenState = false;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800113 mInternalSet = true;
114 mIface->set_property("Status", newValue);
Richard Marian Thomaiyaraf6b87c2019-04-03 23:54:28 +0530115 mInternalSet = false;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800116
117 mValue = newValue;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800118}
119
Chau Lycebb28c2022-10-21 10:01:52 +0000120int ChassisIntrusionPchSensor::readSensor()
Qiang XUe28d1fa2019-02-27 13:50:56 +0800121{
Ed Tanous8a57ec02020-10-09 12:46:52 -0700122 int32_t statusMask = pchRegMaskIntrusion;
123 int32_t statusReg = pchStatusRegIntrusion;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800124
Chau Lycebb28c2022-10-21 10:01:52 +0000125 int32_t value = i2c_smbus_read_byte_data(mBusFd, statusReg);
Alexander Hansen89be6142025-09-18 15:36:16 +0200126 lg2::debug("Pch type: raw value is '{VALUE}'", "VALUE", value);
Qiang XUe28d1fa2019-02-27 13:50:56 +0800127
Chau Lycebb28c2022-10-21 10:01:52 +0000128 if (value < 0)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800129 {
George Liue9a1c9c2025-02-20 15:02:35 +0800130 lg2::error("i2c_smbus_read_byte_data failed");
Qiang XUe28d1fa2019-02-27 13:50:56 +0800131 return -1;
132 }
133
134 // Get status value with mask
Chau Lycebb28c2022-10-21 10:01:52 +0000135 value &= statusMask;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800136
Alexander Hansen89be6142025-09-18 15:36:16 +0200137 lg2::debug("Pch type: masked raw value is '{VALUE}'", "VALUE", value);
Chau Lycebb28c2022-10-21 10:01:52 +0000138 return value;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800139}
140
Chau Lycebb28c2022-10-21 10:01:52 +0000141void ChassisIntrusionPchSensor::pollSensorStatus()
Qiang XUe28d1fa2019-02-27 13:50:56 +0800142{
Chau Lycebb28c2022-10-21 10:01:52 +0000143 std::weak_ptr<ChassisIntrusionPchSensor> weakRef = weak_from_this();
Chau Ly95f49932023-04-19 09:44:55 +0000144
Qiang XUe28d1fa2019-02-27 13:50:56 +0800145 // setting a new experation implicitly cancels any pending async wait
Ed Tanous83db50c2023-03-01 10:20:24 -0800146 mPollTimer.expires_after(std::chrono::seconds(intrusionSensorPollSec));
Qiang XUe28d1fa2019-02-27 13:50:56 +0800147
Chau Lycebb28c2022-10-21 10:01:52 +0000148 mPollTimer.async_wait([weakRef](const boost::system::error_code& ec) {
Qiang XUe28d1fa2019-02-27 13:50:56 +0800149 // case of being canceled
Chau Lycebb28c2022-10-21 10:01:52 +0000150 if (ec == boost::asio::error::operation_aborted)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800151 {
George Liue9a1c9c2025-02-20 15:02:35 +0800152 lg2::error("Timer of intrusion sensor is cancelled");
Qiang XUe28d1fa2019-02-27 13:50:56 +0800153 return;
154 }
Chau Ly95f49932023-04-19 09:44:55 +0000155
Chau Lycebb28c2022-10-21 10:01:52 +0000156 std::shared_ptr<ChassisIntrusionPchSensor> self = weakRef.lock();
157 if (!self)
158 {
George Liue9a1c9c2025-02-20 15:02:35 +0800159 lg2::error("ChassisIntrusionSensor no self");
Chau Lycebb28c2022-10-21 10:01:52 +0000160 return;
161 }
Chau Ly95f49932023-04-19 09:44:55 +0000162
Chau Lycebb28c2022-10-21 10:01:52 +0000163 int value = self->readSensor();
164 if (value < 0)
165 {
166 intrusionSensorPollSec = sensorFailedPollSec;
167 }
168 else
169 {
170 intrusionSensorPollSec = defaultPollSec;
171 self->updateValue(value);
172 }
Chau Ly95f49932023-04-19 09:44:55 +0000173
Chau Lycebb28c2022-10-21 10:01:52 +0000174 // trigger next polling
175 self->pollSensorStatus();
Qiang XUe28d1fa2019-02-27 13:50:56 +0800176 });
177}
178
Chau Lycebb28c2022-10-21 10:01:52 +0000179int ChassisIntrusionGpioSensor::readSensor()
Qiang XUe28d1fa2019-02-27 13:50:56 +0800180{
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800181 mGpioLine.event_read();
182 auto value = mGpioLine.get_value();
Alexander Hansen89be6142025-09-18 15:36:16 +0200183 lg2::debug("Gpio type: raw value is '{VALUE}'", "VALUE", value);
Chau Lycebb28c2022-10-21 10:01:52 +0000184 return value;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800185}
186
Chau Lycebb28c2022-10-21 10:01:52 +0000187void ChassisIntrusionGpioSensor::pollSensorStatus()
Qiang XUe28d1fa2019-02-27 13:50:56 +0800188{
Patrick Williams2aaf7172024-08-16 15:20:40 -0400189 mGpioFd.async_wait(
190 boost::asio::posix::stream_descriptor::wait_read,
191 [this](const boost::system::error_code& ec) {
192 if (ec == boost::system::errc::bad_file_descriptor)
Chau Lycebb28c2022-10-21 10:01:52 +0000193 {
Patrick Williams2aaf7172024-08-16 15:20:40 -0400194 return; // we're being destroyed
Chau Lycebb28c2022-10-21 10:01:52 +0000195 }
Patrick Williams2aaf7172024-08-16 15:20:40 -0400196
197 if (ec)
198 {
George Liue9a1c9c2025-02-20 15:02:35 +0800199 lg2::error("Error on GPIO based intrusion sensor wait event");
Patrick Williams2aaf7172024-08-16 15:20:40 -0400200 }
201 else
202 {
203 int value = readSensor();
204 if (value >= 0)
205 {
206 updateValue(value);
207 }
208 // trigger next polling
209 pollSensorStatus();
210 }
211 });
Qiang XUe28d1fa2019-02-27 13:50:56 +0800212}
213
Chau Ly95f49932023-04-19 09:44:55 +0000214int ChassisIntrusionHwmonSensor::readSensor()
215{
216 int value = 0;
217
218 std::fstream stream(mHwmonPath, std::ios::in | std::ios::out);
219 if (!stream.good())
220 {
George Liue9a1c9c2025-02-20 15:02:35 +0800221 lg2::error("Error reading status at '{PATH}'", "PATH", mHwmonPath);
Chau Ly95f49932023-04-19 09:44:55 +0000222 return -1;
223 }
224
225 std::string line;
226 if (!std::getline(stream, line))
227 {
George Liue9a1c9c2025-02-20 15:02:35 +0800228 lg2::error("Error reading status at '{PATH}'", "PATH", mHwmonPath);
Chau Ly95f49932023-04-19 09:44:55 +0000229 return -1;
230 }
231
232 try
233 {
234 value = std::stoi(line);
Alexander Hansen89be6142025-09-18 15:36:16 +0200235 lg2::debug("Hwmon type: raw value is '{VALUE}'", "VALUE", value);
Chau Ly95f49932023-04-19 09:44:55 +0000236 }
237 catch (const std::invalid_argument& e)
238 {
George Liue9a1c9c2025-02-20 15:02:35 +0800239 lg2::error("Error reading status at '{PATH}': '{ERR}'", "PATH",
240 mHwmonPath, "ERR", e);
Chau Ly95f49932023-04-19 09:44:55 +0000241 return -1;
242 }
243
244 // Reset chassis intrusion status after every reading
245 stream << intrusionStatusHwmonClearValue;
246
247 return value;
248}
249
250void ChassisIntrusionHwmonSensor::pollSensorStatus()
251{
252 std::weak_ptr<ChassisIntrusionHwmonSensor> weakRef = weak_from_this();
253
254 // setting a new experation implicitly cancels any pending async wait
255 mPollTimer.expires_after(std::chrono::seconds(intrusionSensorPollSec));
256
257 mPollTimer.async_wait([weakRef](const boost::system::error_code& ec) {
258 // case of being canceled
259 if (ec == boost::asio::error::operation_aborted)
260 {
George Liue9a1c9c2025-02-20 15:02:35 +0800261 lg2::error("Timer of intrusion sensor is cancelled");
Chau Ly95f49932023-04-19 09:44:55 +0000262 return;
263 }
264
265 std::shared_ptr<ChassisIntrusionHwmonSensor> self = weakRef.lock();
266 if (!self)
267 {
George Liue9a1c9c2025-02-20 15:02:35 +0800268 lg2::error("ChassisIntrusionSensor no self");
Chau Ly95f49932023-04-19 09:44:55 +0000269 return;
270 }
271
272 int value = self->readSensor();
273 if (value < 0)
274 {
275 intrusionSensorPollSec = sensorFailedPollSec;
276 }
277 else
278 {
279 intrusionSensorPollSec = defaultPollSec;
280 self->updateValue(value);
281 }
282
283 // trigger next polling
284 self->pollSensorStatus();
285 });
286}
287
Qiang XUe28d1fa2019-02-27 13:50:56 +0800288int ChassisIntrusionSensor::setSensorValue(const std::string& req,
289 std::string& propertyValue)
290{
Richard Marian Thomaiyaraf6b87c2019-04-03 23:54:28 +0530291 if (!mInternalSet)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800292 {
Chau Lyb318dca2022-10-26 04:12:52 +0000293 /*
294 1. Assuming that setting property in Automatic mode causes
295 no effect but only event logs and propertiesChanged signal
296 (because the property will be updated continuously to the
297 current hardware status anyway), only update Status property
298 and raise rearm flag in Manual rearm mode.
299 2. Only accept Normal value from an external call.
300 */
301 if (!mAutoRearm && req == normalValStr)
302 {
303 mRearmFlag = true;
304 propertyValue = req;
305 mOverridenState = true;
306 }
Qiang XUe28d1fa2019-02-27 13:50:56 +0800307 }
Richard Marian Thomaiyaraf6b87c2019-04-03 23:54:28 +0530308 else if (!mOverridenState)
309 {
310 propertyValue = req;
311 }
Chau Lyb318dca2022-10-26 04:12:52 +0000312 else
313 {
314 return 1;
315 }
316 // Send intrusion event to Redfish
317 if (mValue == normalValStr && propertyValue != normalValStr)
318 {
319 sd_journal_send("MESSAGE=%s", "Chassis intrusion assert event",
320 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
321 "OpenBMC.0.1.ChassisIntrusionDetected", NULL);
322 }
323 else if (mValue == hwIntrusionValStr && propertyValue == normalValStr)
324 {
325 sd_journal_send("MESSAGE=%s", "Chassis intrusion de-assert event",
326 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
327 "OpenBMC.0.1.ChassisIntrusionReset", NULL);
328 }
Qiang XUe28d1fa2019-02-27 13:50:56 +0800329 return 1;
330}
331
Chau Lycebb28c2022-10-21 10:01:52 +0000332void ChassisIntrusionSensor::start()
Qiang XUe28d1fa2019-02-27 13:50:56 +0800333{
Chau Lycebb28c2022-10-21 10:01:52 +0000334 mIface->register_property(
335 "Status", mValue,
336 [&](const std::string& req, std::string& propertyValue) {
Patrick Williams2aaf7172024-08-16 15:20:40 -0400337 return setSensorValue(req, propertyValue);
338 });
Chau Lyb318dca2022-10-26 04:12:52 +0000339 std::string rearmStr = mAutoRearm ? autoRearmStr : manualRearmStr;
340 mIface->register_property("Rearm", rearmStr);
Chau Lycebb28c2022-10-21 10:01:52 +0000341 mIface->initialize();
342 pollSensorStatus();
Qiang XUe28d1fa2019-02-27 13:50:56 +0800343}
344
345ChassisIntrusionSensor::ChassisIntrusionSensor(
Chau Lyb318dca2022-10-26 04:12:52 +0000346 bool autoRearm, sdbusplus::asio::object_server& objServer) :
Patrick Williams2aaf7172024-08-16 15:20:40 -0400347 mValue(normalValStr), mAutoRearm(autoRearm), mObjServer(objServer)
Chau Lycebb28c2022-10-21 10:01:52 +0000348{
349 mIface = mObjServer.add_interface("/xyz/openbmc_project/Chassis/Intrusion",
350 "xyz.openbmc_project.Chassis.Intrusion");
351}
352
353ChassisIntrusionPchSensor::ChassisIntrusionPchSensor(
Chau Lyb318dca2022-10-26 04:12:52 +0000354 bool autoRearm, boost::asio::io_context& io,
355 sdbusplus::asio::object_server& objServer, int busId, int slaveAddr) :
Patrick Williams2aaf7172024-08-16 15:20:40 -0400356 ChassisIntrusionSensor(autoRearm, objServer), mPollTimer(io)
Chau Lycebb28c2022-10-21 10:01:52 +0000357{
358 if (busId < 0 || slaveAddr <= 0)
359 {
Patrick Williams2aaf7172024-08-16 15:20:40 -0400360 throw std::invalid_argument(
361 "Invalid i2c bus " + std::to_string(busId) + " address " +
362 std::to_string(slaveAddr) + "\n");
Chau Lycebb28c2022-10-21 10:01:52 +0000363 }
Chau Ly95f49932023-04-19 09:44:55 +0000364
Chau Lycebb28c2022-10-21 10:01:52 +0000365 mSlaveAddr = slaveAddr;
Chau Ly95f49932023-04-19 09:44:55 +0000366
Chau Lycebb28c2022-10-21 10:01:52 +0000367 std::string devPath = "/dev/i2c-" + std::to_string(busId);
368 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
369 mBusFd = open(devPath.c_str(), O_RDWR | O_CLOEXEC);
370 if (mBusFd < 0)
371 {
372 throw std::invalid_argument("Unable to open " + devPath + "\n");
373 }
374
375 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
376 if (ioctl(mBusFd, I2C_SLAVE_FORCE, mSlaveAddr) < 0)
377 {
378 throw std::runtime_error("Unable to set device address\n");
379 }
380
381 unsigned long funcs = 0;
382
383 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
384 if (ioctl(mBusFd, I2C_FUNCS, &funcs) < 0)
385 {
386 throw std::runtime_error("Don't support I2C_FUNCS\n");
387 }
388
389 if ((funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0U)
390 {
391 throw std::runtime_error(
392 "Do not have I2C_FUNC_SMBUS_READ_BYTE_DATA \n");
393 }
394}
395
396ChassisIntrusionGpioSensor::ChassisIntrusionGpioSensor(
Chau Lyb318dca2022-10-26 04:12:52 +0000397 bool autoRearm, boost::asio::io_context& io,
398 sdbusplus::asio::object_server& objServer, bool gpioInverted) :
Patrick Williams2aaf7172024-08-16 15:20:40 -0400399 ChassisIntrusionSensor(autoRearm, objServer), mGpioInverted(gpioInverted),
400 mGpioFd(io)
Chau Lycebb28c2022-10-21 10:01:52 +0000401{
402 mGpioLine = gpiod::find_line(mPinName);
403 if (!mGpioLine)
404 {
Patrick Williams2aaf7172024-08-16 15:20:40 -0400405 throw std::invalid_argument(
406 "Error finding gpio pin name: " + mPinName + "\n");
Chau Lycebb28c2022-10-21 10:01:52 +0000407 }
408 mGpioLine.request(
409 {"ChassisIntrusionSensor", gpiod::line_request::EVENT_BOTH_EDGES,
410 mGpioInverted ? gpiod::line_request::FLAG_ACTIVE_LOW : 0});
411
412 auto gpioLineFd = mGpioLine.event_get_fd();
413 if (gpioLineFd < 0)
414 {
415 throw std::invalid_argument("Failed to get " + mPinName + " fd\n");
416 }
Chau Ly95f49932023-04-19 09:44:55 +0000417
Chau Lycebb28c2022-10-21 10:01:52 +0000418 mGpioFd.assign(gpioLineFd);
419}
Qiang XUe28d1fa2019-02-27 13:50:56 +0800420
Chau Ly95f49932023-04-19 09:44:55 +0000421ChassisIntrusionHwmonSensor::ChassisIntrusionHwmonSensor(
Chau Lyb318dca2022-10-26 04:12:52 +0000422 bool autoRearm, boost::asio::io_context& io,
423 sdbusplus::asio::object_server& objServer, std::string hwmonName) :
424 ChassisIntrusionSensor(autoRearm, objServer),
Chau Ly95f49932023-04-19 09:44:55 +0000425 mHwmonName(std::move(hwmonName)), mPollTimer(io)
426{
Ed Tanous2e466962025-01-30 10:59:49 -0800427 std::vector<std::filesystem::path> paths;
Chau Ly95f49932023-04-19 09:44:55 +0000428
Ed Tanous2e466962025-01-30 10:59:49 -0800429 if (!findFiles(std::filesystem::path("/sys/class/hwmon"), mHwmonName,
430 paths))
Chau Ly95f49932023-04-19 09:44:55 +0000431 {
432 throw std::invalid_argument("Failed to find hwmon path in sysfs\n");
433 }
434
435 if (paths.empty())
436 {
Patrick Williams2aaf7172024-08-16 15:20:40 -0400437 throw std::invalid_argument(
438 "Hwmon file " + mHwmonName + " can't be found in sysfs\n");
Chau Ly95f49932023-04-19 09:44:55 +0000439 }
440
441 if (paths.size() > 1)
442 {
George Liue9a1c9c2025-02-20 15:02:35 +0800443 lg2::error("Found more than 1 hwmon file to read chassis intrusion"
444 " status. Taking the first one.");
Chau Ly95f49932023-04-19 09:44:55 +0000445 }
446
447 // Expecting only one hwmon file for one given chassis
448 mHwmonPath = paths[0].string();
449
Alexander Hansen89be6142025-09-18 15:36:16 +0200450 lg2::debug(
451 "Found '{NUM_PATHS}' paths for intrusion status. The first path is: '{PATH}'",
452 "NUM_PATHS", paths.size(), "PATH", mHwmonPath);
Chau Ly95f49932023-04-19 09:44:55 +0000453}
454
Qiang XUe28d1fa2019-02-27 13:50:56 +0800455ChassisIntrusionSensor::~ChassisIntrusionSensor()
456{
Chau Lycebb28c2022-10-21 10:01:52 +0000457 mObjServer.remove_interface(mIface);
458}
459
460ChassisIntrusionPchSensor::~ChassisIntrusionPchSensor()
461{
462 mPollTimer.cancel();
463 if (close(mBusFd) < 0)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800464 {
George Liue9a1c9c2025-02-20 15:02:35 +0800465 lg2::error("Failed to close fd '{FD}'", "FD", mBusFd);
Qiang XUe28d1fa2019-02-27 13:50:56 +0800466 }
Chau Lycebb28c2022-10-21 10:01:52 +0000467}
468
469ChassisIntrusionGpioSensor::~ChassisIntrusionGpioSensor()
470{
471 mGpioFd.close();
472 if (mGpioLine)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800473 {
Chau Lycebb28c2022-10-21 10:01:52 +0000474 mGpioLine.release();
Qiang XUe28d1fa2019-02-27 13:50:56 +0800475 }
476}
Chau Ly95f49932023-04-19 09:44:55 +0000477
478ChassisIntrusionHwmonSensor::~ChassisIntrusionHwmonSensor()
479{
480 mPollTimer.cancel();
481}