1 #include "operational-status-monitor.hpp"
2 
3 #include <phosphor-logging/elog.hpp>
4 #include <phosphor-logging/lg2.hpp>
5 
6 namespace phosphor
7 {
8 namespace led
9 {
10 namespace Operational
11 {
12 namespace status
13 {
14 namespace monitor
15 {
16 
17 void Monitor::matchHandler(sdbusplus::message::message& msg)
18 {
19     // Get the ObjectPath of the `xyz.openbmc_project.Inventory.Manager`
20     // service
21     std::string invObjectPath = msg.get_path();
22 
23     // Get all the properties of
24     // "xyz.openbmc_project.State.Decorator.OperationalStatus" interface
25     std::string interfaceName{};
26     std::map<std::string, std::variant<bool>> properties;
27     msg.read(interfaceName, properties);
28 
29     const auto it = properties.find("Functional");
30     if (it != properties.end())
31     {
32         const bool* value = std::get_if<bool>(&it->second);
33         if (!value)
34         {
35             lg2::error(
36                 "Faild to get the Functional property, INVENTORY_PATH = {PATH}",
37                 "PATH", invObjectPath);
38             return;
39         }
40 
41         // See if the Inventory D-Bus object has an association with LED groups
42         // D-Bus object.
43         auto ledGroupPath = getLedGroupPaths(invObjectPath);
44         if (ledGroupPath.empty())
45         {
46             lg2::info(
47                 "The inventory D-Bus object is not associated with the LED "
48                 "group D-Bus object. INVENTORY_PATH = {PATH}",
49                 "PATH", invObjectPath);
50             return;
51         }
52 
53         // Update the Asserted property by the Functional property value.
54         updateAssertedProperty(ledGroupPath, *value);
55     }
56 }
57 
58 const std::vector<std::string>
59     Monitor::getLedGroupPaths(const std::string& inventoryPath) const
60 {
61     // Get endpoints from the rType
62     std::string faultLedAssociation = inventoryPath + "/fault_led_group";
63 
64     // endpoint contains the vector of strings, where each string is a Inventory
65     // D-Bus object that this, associated with this LED Group D-Bus object
66     // pointed to by fru_fault
67     PropertyValue endpoint{};
68 
69     try
70     {
71         endpoint = dBusHandler.getProperty(faultLedAssociation,
72                                            "xyz.openbmc_project.Association",
73                                            "endpoints");
74     }
75     catch (const sdbusplus::exception::exception& e)
76     {
77         lg2::error(
78             "Failed to get endpoints property, ERROR = {ERROR}, PATH = {PATH}",
79             "ERROR", e, "PATH", faultLedAssociation);
80 
81         return {};
82     }
83 
84     auto& endpoints = std::get<std::vector<std::string>>(endpoint);
85 
86     return endpoints;
87 }
88 
89 void Monitor::updateAssertedProperty(
90     const std::vector<std::string>& ledGroupPaths, bool value)
91 {
92     for (const auto& path : ledGroupPaths)
93     {
94         try
95         {
96             // Call "Group Asserted --> true" if the value of Functional is
97             // false Call "Group Asserted --> false" if the value of Functional
98             // is true
99             PropertyValue assertedValue{!value};
100             dBusHandler.setProperty(path, "xyz.openbmc_project.Led.Group",
101                                     "Asserted", assertedValue);
102         }
103         catch (const sdbusplus::exception::exception& e)
104         {
105             lg2::error(
106                 "Failed to set Asserted property, ERROR = {ERROR}, PATH = {PATH}",
107                 "ERROR", e, "PATH", path);
108         }
109     }
110 }
111 } // namespace monitor
112 } // namespace status
113 } // namespace Operational
114 } // namespace led
115 } // namespace phosphor
116