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