blob: 5caefb2dda156e030d660ca2f58db2edc14da294 [file]
#include "tlbmc/deterministic_bmc/offline_config_parser/offline_config_parser.h"
#include <memory>
#include <string>
#include "google/protobuf/any.pb.h"
#include "bus_topology.pb.h"
#include "offline_data.pb.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "tlbmc/deterministic_bmc/offline_config_parser/offline_config_parser_interface.h"
#include "tlbmc/deterministic_bmc/offline_config_parser/proto_reader.h"
#include "fru_i2c.pb.h"
namespace deterministic_bmc {
OfflineConfigParser::OfflineConfigParser(
uhmm::I2cRoot i2c_root,
uhmm::BmcMonitoredComponentsResponse bmc_monitored_components_response,
bool is_uhmm_config_valid)
: i2c_root_(i2c_root),
bmc_monitored_components_response_(bmc_monitored_components_response),
is_uhmm_config_valid_(is_uhmm_config_valid) {}
absl::StatusOr<std::unique_ptr<OfflineConfigParser>>
OfflineConfigParser::Create(ConfigParserOptions options) {
if ((options.uhmm_offline_data_proto_format == ProtoFormat::kTextProto &&
options.uhmm_offline_data_path_txtpb.empty()) ||
(options.uhmm_offline_data_proto_format == ProtoFormat::kBinaryProto &&
options.uhmm_offline_data_path_pb.empty())) {
return absl::InvalidArgumentError(
"Failed to create OfflineConfigParser: the file path for the selected "
"proto format must be provided.");
}
std::string uhmm_offline_data_path =
options.uhmm_offline_data_proto_format == ProtoFormat::kTextProto
? options.uhmm_offline_data_path_txtpb
: options.uhmm_offline_data_path_pb;
absl::StatusOr<uhmm::OfflineData> offline_data =
ProtoReader<uhmm::OfflineData>::ReadProtoFromFile(
uhmm_offline_data_path, options.uhmm_offline_data_proto_format);
uhmm::I2cRoot i2c_root;
uhmm::BmcMonitoredComponentsResponse bmc_monitored_components_response;
if (!offline_data.ok()) {
LOG(ERROR) << "OfflineConfigParser::Create: ProtoReader::ReadProtoFromFile "
"failed, status: "
<< offline_data.status();
return absl::WrapUnique(new OfflineConfigParser(
i2c_root, bmc_monitored_components_response, false));
}
// We expect the UHMM config now contain exactly two protos: I2cRoot and
// BmcMonitoredComponentsResponse. Both needs to be present for the UHMM
// config to be valid.
if (offline_data->data_size() != 2) {
return absl::WrapUnique(new OfflineConfigParser(
i2c_root, bmc_monitored_components_response, false));
}
bool i2c_root_found = false;
bool bmc_monitored_components_response_found = false;
for (const auto& data : offline_data->data()) {
if (data.Is<uhmm::I2cRoot>()) {
if (i2c_root_found) {
LOG(ERROR) << "OfflineConfigParser::Create: duplicate I2cRoot found";
return absl::WrapUnique(new OfflineConfigParser(
uhmm::I2cRoot(), uhmm::BmcMonitoredComponentsResponse(), false));
}
data.UnpackTo(&i2c_root);
i2c_root_found = true;
} else if (data.Is<uhmm::BmcMonitoredComponentsResponse>()) {
if (bmc_monitored_components_response_found) {
LOG(ERROR) << "OfflineConfigParser::Create: duplicate "
"BmcMonitoredComponentsResponse found";
return absl::WrapUnique(new OfflineConfigParser(
uhmm::I2cRoot(), uhmm::BmcMonitoredComponentsResponse(), false));
}
data.UnpackTo(&bmc_monitored_components_response);
bmc_monitored_components_response_found = true;
}
}
if (i2c_root_found && bmc_monitored_components_response_found) {
return absl::WrapUnique(new OfflineConfigParser(
i2c_root, bmc_monitored_components_response, true));
}
LOG(ERROR) << "OfflineConfigParser::Create: UHMM config is invalid, "
"I2cRoot found: "
<< i2c_root_found << ", "
<< "BmcMonitoredComponentsResponse found: "
<< bmc_monitored_components_response_found;
return absl::WrapUnique(new OfflineConfigParser(
uhmm::I2cRoot(), uhmm::BmcMonitoredComponentsResponse(), false));
}
absl::StatusOr<uhmm::I2cRoot> OfflineConfigParser::GetI2cRoot() const {
if (!is_uhmm_config_valid_) {
return absl::FailedPreconditionError("UHMM config is invalid.");
}
return i2c_root_;
}
absl::StatusOr<uhmm::BmcMonitoredComponentsResponse>
OfflineConfigParser::GetBmcMonitoredComponentsResponse() const {
if (!is_uhmm_config_valid_) {
return absl::FailedPreconditionError("UHMM config is invalid.");
}
return bmc_monitored_components_response_;
}
} // namespace deterministic_bmc