blob: b5a1c3ee508ed62e3700fd3462ac5b809c415fd7 [file] [log] [blame]
#include "tlbmc/sensors/ixc_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 "hal_common_config.pb.h"
#include "hwmon_temp_sensor_config.pb.h"
#include "tlbmc/hal/sysfs/hwmon.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/hwmon_based_sensor.h"
namespace milotic_tlbmc {
IXcHwmonBasedSensor::IXcHwmonBasedSensor(
const std::string& input_dev_path,
const std::shared_ptr<boost::asio::io_context>& io_context,
SensorAttributesStatic&& sensor_attributes_static,
const ThresholdConfigs& threshold_configs,
std::optional<NotificationCb> on_batch_notify,
const HwmonSysfs& hwmon_sysfs)
: HwmonBasedSensor(input_dev_path, io_context,
std::move(sensor_attributes_static),
threshold_configs, on_batch_notify),
hwmon_sysfs_(&hwmon_sysfs) {}
absl::StatusOr<boost::filesystem::path>
IXcHwmonBasedSensor::CreateIXcDeviceAndReturnsHwmonPath(
const HalCommonConfig& hal_config, std::string_view driver_name,
const HwmonSysfs& hwmon_sysfs) {
// If the device is already created, in the current implementation we don't
// create it again.
if (absl::Status status = hwmon_sysfs.NewDevice(hal_config, driver_name);
!status.ok() && status.code() != absl::StatusCode::kAlreadyExists) {
return status;
}
if (!hwmon_sysfs.IsDevicePresent(hal_config)) {
return absl::InternalError(absl::StrCat("Failed to find device ",
hal_config, " after creating it"));
}
// Now the device is created, e.g.,
// /sys/bus/i2c/devices/i2c-24/24-005c/
boost::filesystem::path device_path =
hwmon_sysfs.GetBusPath(hal_config.bus()) /
hwmon_sysfs.GetDeviceDirectoryName(hal_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