blob: d811c36c2b62ab094850e76d251cd0728b197b9d [file]
#include "tlbmc/sensors/shared_mem_based_sensor.h"
#include <cstdint>
#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 "absl/strings/substitute.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 "boost/filesystem.hpp" // NOLINT: boost::filesystem is commonly used in BMC
#include "boost/filesystem/operations.hpp" // NOLINT: boost::filesystem is commonly used in BMC
#include "boost/system/detail/error_code.hpp" // NOLINT: boost::asio is commonly used in BMC
// NOLINTNEXTLINE: keep this so BUILD file will keep liburing
#include "liburing.h" // IWYU pragma: keep
#include "entity_common_config.pb.h"
#include "hal_common_config.pb.h"
#include "reading_range_config.pb.h"
#include "shared_mem_sensor_config.pb.h"
#include "threshold_config.pb.h"
#include "tlbmc/hal/shared_mem/server_interface.h"
#include "tlbmc/hal/shared_mem/static_server_impl.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/sensor.h"
#include "tlbmc/sensors/sync_polling_sensor.h"
#include "tlbmc/time/time.h"
namespace milotic_tlbmc {
constexpr std::string_view kShmSensorKeyPrefix = "sharedmem_";
bool SharedMemBasedSensor::IsSharedMemSensorKey(const std::string& key) {
return absl::StartsWith(key, kShmSensorKeyPrefix);
}
absl::StatusOr<std::shared_ptr<Sensor>> SharedMemBasedSensor::Create(
const SharedMemSensorConfig& config,
const std::shared_ptr<boost::asio::io_context>& io_context,
std::optional<NotificationCb> on_batch_notify) {
SensorInstanceProperties mutable_instance_properties =
config.instance_properties();
mutable_instance_properties.set_name(
absl::StrCat(kShmSensorKeyPrefix, config.instance_properties().name()));
// Populate default related item if not specified.
if (!config.instance_properties().has_related_item()) {
mutable_instance_properties.mutable_related_item()->set_type(
RESOURCE_TYPE_BOARD);
mutable_instance_properties.mutable_related_item()->set_id(
config.entity_common_config().board_config_key());
}
return std::make_shared<SharedMemBasedSensor>(
Token(), config.type(), config.entity_common_config(),
mutable_instance_properties, io_context, on_batch_notify);
}
SharedMemBasedSensor::SharedMemBasedSensor(
Token token, SharedMemSensorType sensor_type,
const EntityCommonConfig& entity_common_config,
const SensorInstanceProperties& sensor_properties,
const std::shared_ptr<boost::asio::io_context>& io_context,
std::optional<NotificationCb> on_batch_notify)
: SyncPollingSensor(CreateStaticAttributes(sensor_properties,
/*hal_common_config=*/{},
entity_common_config),
sensor_properties.thresholds(), io_context,
on_batch_notify),
sensor_type_(sensor_type),
sensor_name_(sensor_properties.name()) {}
absl::StatusOr<SensorValue> SharedMemBasedSensor::ReadSensorData() {
// Get the sensor value from the shared memory.
absl::StatusOr<std::pair<float, uint64_t>> sensor_value =
milotic_tlbmc::StaticSharedMemoryServer::GetInstance().ReadSensorValue(
sensor_name_);
if (!sensor_value.ok()) {
return absl::Status(
sensor_value.status().code(),
absl::Substitute(
"Failed to read sensor value from shared memory: $0 with error: $1",
sensor_name_, sensor_value.status().message()));
}
SensorValue sensor_data;
// milliseconds to timestamp
*sensor_data.mutable_source_timestamp() =
MilliSecondsToTimestamp(sensor_value->second);
*sensor_data.mutable_timestamp() = milotic_tlbmc::Now();
sensor_data.set_reading(static_cast<double>(sensor_value->first));
return sensor_data;
}
} // namespace milotic_tlbmc