| #include "tlbmc/sensors/i2c_hwmon_based_sensor.h" |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <string_view> |
| #include <utility> |
| |
| #include "google/protobuf/duration.pb.h" |
| #include "absl/log/log.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/match.h" |
| #include "absl/strings/str_cat.h" |
| #include "boost/asio.hpp" // NOLINT: boost::asio is commonly used in BMC |
| #include "boost/asio/error.hpp" // NOLINT |
| #include "boost/asio/random_access_file.hpp" // NOLINT: boost::asio is commonly used in BMC |
| #include "boost/filesystem.hpp" // NOLINT: boost::filesystem is commonly used in BMC |
| #include "boost/filesystem/operations.hpp" // NOLINT |
| #include "boost/system/detail/error_code.hpp" // NOLINT: boost::asio is commonly used in BMC |
| #include "hwmon_temp_sensor_config.pb.h" |
| #include "i2c_common_config.pb.h" |
| #include "tlbmc/hal/sysfs/i2c.h" |
| #include "resource.pb.h" |
| #include "sensor.pb.h" |
| #include "tlbmc/sensors/hwmon_based_sensor.h" |
| |
| namespace milotic_tlbmc { |
| |
| I2cHwmonBasedSensor::I2cHwmonBasedSensor( |
| const std::string& input_dev_path, |
| const std::shared_ptr<boost::asio::io_context>& io_context, |
| SensorAttributesStatic&& sensor_attributes_static, |
| std::optional<NotificationCb> on_batch_notify) |
| : HwmonBasedSensor(input_dev_path, io_context, |
| std::move(sensor_attributes_static), on_batch_notify) {} |
| |
| absl::StatusOr<boost::filesystem::path> |
| I2cHwmonBasedSensor::CreateDeviceAndReturnsHwmonPath( |
| const I2cCommonConfig& i2c_config, std::string_view driver_name, |
| const I2cSysfs& i2c_sysfs) { |
| // If the device is already created, in the current implementation we don't |
| // create it again. |
| if (absl::Status status = i2c_sysfs.NewDevice(i2c_config, driver_name); |
| !status.ok() && status.code() != absl::StatusCode::kAlreadyExists) { |
| return status; |
| } |
| |
| if (!i2c_sysfs.IsDevicePresent(i2c_config)) { |
| return absl::InternalError(absl::StrCat("Failed to find device ", |
| i2c_config, " after creating it")); |
| } |
| |
| // Now the device is created, e.g., |
| // /sys/bus/i2c/devices/i2c-24/24-005c/ |
| boost::filesystem::path device_path = |
| i2c_sysfs.Geti2cBusPath(i2c_config.bus()) / |
| I2cSysfs::GetDeviceDirectoryName(i2c_config); |
| |
| if (!boost::filesystem::is_directory(device_path / "hwmon")) { |
| return absl::InternalError( |
| absl::StrCat("Failed to find hwmon under ", device_path.string())); |
| } |
| |
| boost::filesystem::path hwmon_path; |
| bool found_hwmon = false; |
| for (const auto& entry : |
| boost::filesystem::directory_iterator(device_path / "hwmon")) { |
| // Look for something like hwmon10 |
| if (absl::StartsWith(entry.path().filename().string(), "hwmon")) { |
| found_hwmon = true; |
| hwmon_path = entry.path(); |
| break; |
| } |
| } |
| |
| if (!found_hwmon) { |
| return absl::InternalError( |
| absl::StrCat("Failed to find hwmon for ", device_path.string())); |
| } |
| return hwmon_path; |
| } |
| |
| } // namespace milotic_tlbmc |