| Alexander Hansen | 8c4b1d9 | 2024-11-04 14:06:24 +0100 | [diff] [blame] | 1 | /* | 
 | 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 |  | 
 | 17 | PHOSPHOR_LOG2_USING; | 
 | 18 |  | 
| Alexander Hansen | b0f1571 | 2025-06-18 17:48:23 +0200 | [diff] [blame] | 19 | using DevicePresenceProperties = sdbusplus::common::xyz::openbmc_project:: | 
 | 20 |     inventory::source::DevicePresence::properties_t; | 
 | 21 |  | 
| Alexander Hansen | 8c4b1d9 | 2024-11-04 14:06:24 +0100 | [diff] [blame] | 22 | namespace gpio_presence | 
 | 23 | { | 
 | 24 |  | 
 | 25 | DevicePresence::DevicePresence( | 
 | 26 |     sdbusplus::async::context& ctx, const std::vector<std::string>& gpioNames, | 
 | 27 |     const std::vector<uint64_t>& gpioValues, const std::string& deviceName, | 
 | 28 |     const std::unordered_map<std::string, bool>& gpioState) : | 
 | 29 |     deviceName(deviceName), gpioState(gpioState), ctx(ctx) | 
 | 30 | { | 
 | 31 |     for (size_t i = 0; i < gpioNames.size(); i++) | 
 | 32 |     { | 
 | 33 |         GPIO_POLARITY polarity = | 
 | 34 |             (gpioValues[i] == 0) ? ACTIVE_LOW : ACTIVE_HIGH; | 
 | 35 |         gpioPolarity[gpioNames[i]] = polarity; | 
 | 36 |     } | 
 | 37 | } | 
 | 38 |  | 
 | 39 | auto DevicePresence::updateGPIOPresence(const std::string& gpioLine) -> void | 
 | 40 | { | 
 | 41 |     if (!gpioPolarity.contains(gpioLine)) | 
 | 42 |     { | 
 | 43 |         return; | 
 | 44 |     } | 
 | 45 |  | 
 | 46 |     updateDbusInterfaces(); | 
 | 47 | } | 
 | 48 |  | 
 | 49 | auto DevicePresence::getObjPath() const -> sdbusplus::message::object_path | 
 | 50 | { | 
 | 51 |     sdbusplus::message::object_path objPathBase( | 
 | 52 |         "/xyz/openbmc_project/GPIODeviceDetected/"); | 
 | 53 |     sdbusplus::message::object_path objPath = objPathBase / deviceName; | 
 | 54 |     return objPath; | 
 | 55 | } | 
 | 56 |  | 
 | 57 | auto DevicePresence::isPresent() -> bool | 
 | 58 | { | 
 | 59 |     for (auto& [name, polarity] : gpioPolarity) | 
 | 60 |     { | 
 | 61 |         if (!gpioState.contains(name)) | 
 | 62 |         { | 
 | 63 |             error("GPIO {NAME} not in cached state", "NAME", name); | 
 | 64 |             return false; | 
 | 65 |         } | 
 | 66 |  | 
 | 67 |         const bool state = gpioState.at(name); | 
 | 68 |  | 
 | 69 |         if (state && polarity == ACTIVE_LOW) | 
 | 70 |         { | 
 | 71 |             return false; | 
 | 72 |         } | 
 | 73 |         if (!state && polarity == ACTIVE_HIGH) | 
 | 74 |         { | 
 | 75 |             return false; | 
 | 76 |         } | 
 | 77 |     } | 
 | 78 |  | 
 | 79 |     return true; | 
 | 80 | } | 
 | 81 |  | 
 | 82 | auto DevicePresence::updateDbusInterfaces() -> void | 
 | 83 | { | 
 | 84 |     debug("Updating dbus interface for config {OBJPATH}", "OBJPATH", | 
 | 85 |           deviceName); | 
 | 86 |  | 
 | 87 |     const bool present = isPresent(); | 
 | 88 |     sdbusplus::message::object_path objPath = getObjPath(); | 
 | 89 |  | 
 | 90 |     if (present && !detectedIface) | 
 | 91 |     { | 
 | 92 |         info("Detected {NAME} as present, adding dbus interface", "NAME", | 
 | 93 |              deviceName); | 
 | 94 |  | 
| Alexander Hansen | b0f1571 | 2025-06-18 17:48:23 +0200 | [diff] [blame] | 95 |         detectedIface = std::make_unique<DevicePresenceInterface>( | 
 | 96 |             ctx, objPath.str.c_str(), DevicePresenceProperties{deviceName}); | 
| Alexander Hansen | 8c4b1d9 | 2024-11-04 14:06:24 +0100 | [diff] [blame] | 97 |  | 
 | 98 |         detectedIface->emit_added(); | 
 | 99 |     } | 
 | 100 |  | 
 | 101 |     if (!present && detectedIface) | 
 | 102 |     { | 
 | 103 |         info("Detected {NAME} as absent, removing dbus interface", "NAME", | 
 | 104 |              deviceName); | 
 | 105 |         detectedIface->emit_removed(); | 
 | 106 |  | 
 | 107 |         detectedIface.reset(); | 
 | 108 |     } | 
 | 109 | } | 
 | 110 |  | 
 | 111 | } // namespace gpio_presence |