blob: 00e0a07598acaaebe172358b5031bbd0f98dae55 [file]
#include "tlbmc/hal/fru_scanner_usb.h"
#include <glob.h>
#include <filesystem> // NOLINT: filesystem is available on BMC
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "tlbmc/hal/fru_scanner.h"
#include "status.pb.h"
namespace milotic_tlbmc {
std::unique_ptr<FruScannerUsb> FruScannerUsb::Create(const Options& options) {
return absl::WrapUnique(
new FruScannerUsb(options.soc_path, options.components));
}
absl::StatusOr<std::vector<std::unique_ptr<UsbFruInfo>>>
FruScannerUsb::ScanAllUsbFrus() const {
std::vector<std::unique_ptr<UsbFruInfo>> usb_frus;
usb_frus.reserve(usb_components_.size());
for (const auto& component : usb_components_) {
auto usb_fru = std::make_unique<UsbFruInfo>();
usb_fru->expected_barepath = component.barepath();
std::string rel_path = component.sysfs_path();
if (!rel_path.empty() && rel_path[0] == '/') {
rel_path = rel_path.substr(1);
}
std::string full_pattern =
(std::filesystem::path(soc_path_) / rel_path).string();
glob_t glob_result = {};
int ret = glob(full_pattern.c_str(), GLOB_NOSORT | GLOB_ERR, nullptr,
&glob_result);
if (ret == 0) {
usb_fru->presence_status = PresenceStatus::PRESENCE_STATUS_PRESENT;
globfree(&glob_result);
} else if (ret == GLOB_NOMATCH) {
usb_fru->presence_status = PresenceStatus::PRESENCE_STATUS_NOT_FOUND;
globfree(&glob_result);
} else {
globfree(&glob_result);
return absl::InternalError(
absl::StrCat("glob() failed when scanning USB FRU path '",
full_pattern, "' with error code: ", ret));
}
usb_frus.push_back(std::move(usb_fru));
}
return usb_frus;
}
} // namespace milotic_tlbmc