blob: f11c36486cc8bc588fe637ca62ba3ac46adf6ee3 [file] [log] [blame]
#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