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 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 95 detectedIface = std::make_unique<DevicePresenceInterface>( 96 ctx, objPath.str.c_str(), DevicePresenceProperties{deviceName}); 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 112