blob: 0ee8ecd409366b8fbbfbd04a318e57bf36c70788 [file]
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_ADC_SENSOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_ADC_SENSOR_H_
#include <array>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
#include "boost/asio.hpp" //NOLINT: boost::asio is commonly used in BMC
#include "boost/asio/random_access_file.hpp" // NOLINT: boost::asio is commonly used in BMC
#include "adc_sensor_config.pb.h"
#include "entity_common_config.pb.h"
#include "sensor_instance_properties.pb.h"
#include "tlbmc/hal/sysfs/i2c.h"
#include "tlbmc/hal/sysfs/iio.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/polling_base_sensor.h"
namespace milotic_tlbmc {
struct AdcSensorParameters {
const std::string device_name;
const AdcChannel channel_config;
const HalCommonConfig hal_common_config;
const EntityCommonConfig entity_common_config;
const std::shared_ptr<boost::asio::io_context> io_context;
const AdcSensorType type = ADC_SENSOR_TYPE0_UNKNOWN;
};
class AdcSensor : public PollingBaseSensor,
public std::enable_shared_from_this<AdcSensor> {
public:
static absl::StatusOr<std::shared_ptr<AdcSensor>> Create(
const AdcSensorParameters& params, const IioSysfs& iio_sysfs,
const I2cSysfs& i2c_sysfs,
std::optional<NotificationCb> on_batch_notify = std::nullopt);
AdcSensor(const AdcSensorParameters& params,
const SensorInstanceProperties& instance_properties,
const std::string& full_path,
std::optional<NotificationCb> on_batch_notify = std::nullopt);
~AdcSensor() override;
void RefreshOnceAsync(
absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)>
callback) override;
protected:
// Subclasses should call this in their Create method or constructor after
// the object is fully constructed (if needed, but here we can call it in
// subclasses' own Create after make_shared).
// Actually, let's just make it a normal method that subclasses call.
absl::StatusOr<std::string> GetFileScalePath() const;
absl::StatusOr<double> GetFileScaleValue() const;
void HandleReadDone(
const boost::system::error_code& error, size_t bytes_read,
absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)>
callback);
void Init();
static absl::StatusOr<std::string_view> GetDriverName(
AdcSensorType sensor_type);
static absl::StatusOr<boost::filesystem::path>
CreateAdcDeviceAndReturnsHwmonPath(const HalCommonConfig& hal_config,
std::string_view driver_name,
const I2cSysfs& i2c_sysfs);
static absl::StatusOr<std::shared_ptr<AdcSensor>> CreateFailedSensor(
const AdcSensorParameters& params,
const SensorInstanceProperties& instance_properties,
std::optional<NotificationCb> on_batch_notify,
std::string_view error_message);
const std::string device_name_;
const std::string file_name_;
const std::optional<uint64_t> gpio_threshold_millivolts_;
std::shared_ptr<boost::asio::io_context> io_context_;
boost::asio::posix::stream_descriptor sd_input_device_;
const std::string full_path_;
std::array<char, 128> read_buffer_;
double scale_value_ = 1.0;
private:
static absl::StatusOr<std::string> FindFullPathViaI2c(
const AdcSensorParameters& params,
const boost::filesystem::path& device_base_path);
static absl::StatusOr<std::string> FindFullPathViaIio(
const AdcSensorParameters& params, const IioSysfs& iio_sysfs);
friend class AdcSensorTest;
};
} // namespace milotic_tlbmc
#endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_ADC_SENSOR_H_