blob: 44d6e6ae03a40aefd907f09f10bf0d4433bae0a5 [file] [log] [blame]
Alexander Hansen8c4b1d92024-11-04 14:06:24 +01001/*
2 * SPDX-FileCopyrightText: Copyright (c) 2022-2024. All rights
3 * reserved. SPDX-License-Identifier: Apache-2.0
4 */
5
6#include "device_presence.hpp"
7
8#include <phosphor-logging/lg2.hpp>
9#include <sdbusplus/message/native_types.hpp>
10#include <xyz/openbmc_project/Configuration/GPIODeviceDetect/client.hpp>
11#include <xyz/openbmc_project/Configuration/GPIODeviceDetect/common.hpp>
12#include <xyz/openbmc_project/Inventory/Source/DevicePresence/aserver.hpp>
13
14#include <string>
15#include <vector>
16
17PHOSPHOR_LOG2_USING;
18
19namespace gpio_presence
20{
21
22DevicePresence::DevicePresence(
23 sdbusplus::async::context& ctx, const std::vector<std::string>& gpioNames,
24 const std::vector<uint64_t>& gpioValues, const std::string& deviceName,
25 const std::unordered_map<std::string, bool>& gpioState) :
26 deviceName(deviceName), gpioState(gpioState), ctx(ctx)
27{
28 for (size_t i = 0; i < gpioNames.size(); i++)
29 {
30 GPIO_POLARITY polarity =
31 (gpioValues[i] == 0) ? ACTIVE_LOW : ACTIVE_HIGH;
32 gpioPolarity[gpioNames[i]] = polarity;
33 }
34}
35
36auto DevicePresence::updateGPIOPresence(const std::string& gpioLine) -> void
37{
38 if (!gpioPolarity.contains(gpioLine))
39 {
40 return;
41 }
42
43 updateDbusInterfaces();
44}
45
46auto DevicePresence::getObjPath() const -> sdbusplus::message::object_path
47{
48 sdbusplus::message::object_path objPathBase(
49 "/xyz/openbmc_project/GPIODeviceDetected/");
50 sdbusplus::message::object_path objPath = objPathBase / deviceName;
51 return objPath;
52}
53
54auto DevicePresence::isPresent() -> bool
55{
56 for (auto& [name, polarity] : gpioPolarity)
57 {
58 if (!gpioState.contains(name))
59 {
60 error("GPIO {NAME} not in cached state", "NAME", name);
61 return false;
62 }
63
64 const bool state = gpioState.at(name);
65
66 if (state && polarity == ACTIVE_LOW)
67 {
68 return false;
69 }
70 if (!state && polarity == ACTIVE_HIGH)
71 {
72 return false;
73 }
74 }
75
76 return true;
77}
78
79auto DevicePresence::updateDbusInterfaces() -> void
80{
81 debug("Updating dbus interface for config {OBJPATH}", "OBJPATH",
82 deviceName);
83
84 const bool present = isPresent();
85 sdbusplus::message::object_path objPath = getObjPath();
86
87 if (present && !detectedIface)
88 {
89 info("Detected {NAME} as present, adding dbus interface", "NAME",
90 deviceName);
91
92 detectedIface =
93 std::make_unique<DevicePresenceInterface>(ctx, objPath.str.c_str());
94
95 detectedIface->name(deviceName);
96
97 detectedIface->emit_added();
98 }
99
100 if (!present && detectedIface)
101 {
102 info("Detected {NAME} as absent, removing dbus interface", "NAME",
103 deviceName);
104 detectedIface->emit_removed();
105
106 detectedIface.reset();
107 }
108}
109
110} // namespace gpio_presence