| #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_ |