blob: 140299648d2147b3e0fac7722e1413aac2da3640 [file] [log] [blame] [edit]
/*
* SPDX-FileCopyrightText: Copyright (c) 2022-2024. All rights
* reserved. SPDX-License-Identifier: Apache-2.0
*/
#include "device_presence.hpp"
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/message/native_types.hpp>
#include <xyz/openbmc_project/Configuration/GPIODeviceDetect/client.hpp>
#include <xyz/openbmc_project/Configuration/GPIODeviceDetect/common.hpp>
#include <xyz/openbmc_project/Inventory/Source/DevicePresence/aserver.hpp>
#include <string>
#include <vector>
PHOSPHOR_LOG2_USING;
using DevicePresenceProperties = sdbusplus::common::xyz::openbmc_project::
inventory::source::DevicePresence::properties_t;
namespace gpio_presence
{
DevicePresence::DevicePresence(
sdbusplus::async::context& ctx, const std::vector<std::string>& gpioNames,
const std::vector<uint64_t>& gpioValues, const std::string& deviceName,
const std::unordered_map<std::string, bool>& gpioState) :
deviceName(deviceName), gpioState(gpioState), ctx(ctx)
{
for (size_t i = 0; i < gpioNames.size(); i++)
{
GPIO_POLARITY polarity =
(gpioValues[i] == 0) ? ACTIVE_LOW : ACTIVE_HIGH;
gpioPolarity[gpioNames[i]] = polarity;
}
}
auto DevicePresence::updateGPIOPresence(const std::string& gpioLine) -> void
{
if (!gpioPolarity.contains(gpioLine))
{
return;
}
updateDbusInterfaces();
}
auto DevicePresence::getObjPath() const -> sdbusplus::message::object_path
{
sdbusplus::message::object_path objPathBase(
"/xyz/openbmc_project/GPIODeviceDetected/");
sdbusplus::message::object_path objPath = objPathBase / deviceName;
return objPath;
}
auto DevicePresence::isPresent() -> bool
{
for (auto& [name, polarity] : gpioPolarity)
{
if (!gpioState.contains(name))
{
error("GPIO {NAME} not in cached state", "NAME", name);
return false;
}
const bool state = gpioState.at(name);
if (state && polarity == ACTIVE_LOW)
{
return false;
}
if (!state && polarity == ACTIVE_HIGH)
{
return false;
}
}
return true;
}
auto DevicePresence::updateDbusInterfaces() -> void
{
debug("Updating dbus interface for config {OBJPATH}", "OBJPATH",
deviceName);
const bool present = isPresent();
sdbusplus::message::object_path objPath = getObjPath();
if (present && !detectedIface)
{
info("Detected {NAME} as present, adding dbus interface", "NAME",
deviceName);
detectedIface = std::make_unique<DevicePresenceInterface>(
ctx, objPath.str.c_str(), DevicePresenceProperties{deviceName});
detectedIface->emit_added();
}
if (!present && detectedIface)
{
info("Detected {NAME} as absent, removing dbus interface", "NAME",
deviceName);
detectedIface->emit_removed();
detectedIface.reset();
}
}
} // namespace gpio_presence