xref: /openbmc/phosphor-led-manager/fault-monitor/fru-fault-monitor.cpp (revision 3c6f29a0d0c89186e5f8fe1dfb12f76a6e448b28)
1*3c6f29a0SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp>
2*3c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp"
3*3c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Mapper/error.hpp"
4*3c6f29a0SDhruvaraj Subhashchandran #include "elog-errors.hpp"
559b86cd7SDhruvaraj Subhashchandran #include "fru-fault-monitor.hpp"
6*3c6f29a0SDhruvaraj Subhashchandran 
759b86cd7SDhruvaraj Subhashchandran namespace phosphor
859b86cd7SDhruvaraj Subhashchandran {
959b86cd7SDhruvaraj Subhashchandran namespace led
1059b86cd7SDhruvaraj Subhashchandran {
1159b86cd7SDhruvaraj Subhashchandran namespace fru
1259b86cd7SDhruvaraj Subhashchandran {
1359b86cd7SDhruvaraj Subhashchandran namespace fault
1459b86cd7SDhruvaraj Subhashchandran {
1559b86cd7SDhruvaraj Subhashchandran namespace monitor
1659b86cd7SDhruvaraj Subhashchandran {
1759b86cd7SDhruvaraj Subhashchandran 
18*3c6f29a0SDhruvaraj Subhashchandran using namespace phosphor::logging;
19*3c6f29a0SDhruvaraj Subhashchandran 
20*3c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_BUSNAME   = "xyz.openbmc_project.ObjectMapper";
21*3c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_OBJ_PATH  = "/xyz/openbmc_project/object_mapper";
22*3c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_IFACE     = "xyz.openbmc_project.ObjectMapper";
23*3c6f29a0SDhruvaraj Subhashchandran constexpr auto OBJMGR_IFACE     = "org.freedesktop.DBus.ObjectManager";
24*3c6f29a0SDhruvaraj Subhashchandran constexpr auto LED_GROUPS       = "/xyz/openbmc_project/led/groups/";
25*3c6f29a0SDhruvaraj Subhashchandran constexpr auto LOG_PATH         = "/xyz/openbmc_project/logging";
26*3c6f29a0SDhruvaraj Subhashchandran 
27*3c6f29a0SDhruvaraj Subhashchandran using AssociationList = std::vector<std::tuple<
28*3c6f29a0SDhruvaraj Subhashchandran                         std::string, std::string, std::string>>;
29*3c6f29a0SDhruvaraj Subhashchandran using MethodErr  =
30*3c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
31*3c6f29a0SDhruvaraj Subhashchandran using ObjectNotFoundErr =
32*3c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
33*3c6f29a0SDhruvaraj Subhashchandran using AssociationRetrieveErr =
34*3c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::
35*3c6f29a0SDhruvaraj Subhashchandran     Led::Fru::Monitor::Error::AssociationRetrieveError;
36*3c6f29a0SDhruvaraj Subhashchandran using InventoryPathErr =
37*3c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::
38*3c6f29a0SDhruvaraj Subhashchandran     Led::Fru::Monitor::Error::InventoryPathError;
39*3c6f29a0SDhruvaraj Subhashchandran 
40*3c6f29a0SDhruvaraj Subhashchandran std::string getService(sdbusplus::bus::bus& bus,
41*3c6f29a0SDhruvaraj Subhashchandran                        const std::string& path)
42*3c6f29a0SDhruvaraj Subhashchandran {
43*3c6f29a0SDhruvaraj Subhashchandran     auto mapper = bus.new_method_call(MAPPER_BUSNAME,
44*3c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_OBJ_PATH,
45*3c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_IFACE, "GetObject");
46*3c6f29a0SDhruvaraj Subhashchandran     mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
47*3c6f29a0SDhruvaraj Subhashchandran     auto mapperResponseMsg = bus.call(mapper);
48*3c6f29a0SDhruvaraj Subhashchandran     if (mapperResponseMsg.is_method_error())
49*3c6f29a0SDhruvaraj Subhashchandran     {
50*3c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
51*3c6f29a0SDhruvaraj Subhashchandran         elog<MethodErr>(
52*3c6f29a0SDhruvaraj Subhashchandran             MethodError::METHOD_NAME("GetObject"),
53*3c6f29a0SDhruvaraj Subhashchandran             MethodError::PATH(path.c_str()),
54*3c6f29a0SDhruvaraj Subhashchandran             MethodError::INTERFACE(
55*3c6f29a0SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
56*3c6f29a0SDhruvaraj Subhashchandran     }
57*3c6f29a0SDhruvaraj Subhashchandran 
58*3c6f29a0SDhruvaraj Subhashchandran     std::map<std::string, std::vector<std::string>> mapperResponse;
59*3c6f29a0SDhruvaraj Subhashchandran     mapperResponseMsg.read(mapperResponse);
60*3c6f29a0SDhruvaraj Subhashchandran     if (mapperResponse.empty())
61*3c6f29a0SDhruvaraj Subhashchandran     {
62*3c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
63*3c6f29a0SDhruvaraj Subhashchandran         elog<ObjectNotFoundErr>(
64*3c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::METHOD_NAME("GetObject"),
65*3c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::PATH(path.c_str()),
66*3c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::INTERFACE(
67*3c6f29a0SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
68*3c6f29a0SDhruvaraj Subhashchandran     }
69*3c6f29a0SDhruvaraj Subhashchandran 
70*3c6f29a0SDhruvaraj Subhashchandran     return mapperResponse.cbegin()->first;
71*3c6f29a0SDhruvaraj Subhashchandran }
72*3c6f29a0SDhruvaraj Subhashchandran 
7359b86cd7SDhruvaraj Subhashchandran void action(sdbusplus::bus::bus& bus,
74*3c6f29a0SDhruvaraj Subhashchandran             const std::string& path,
7559b86cd7SDhruvaraj Subhashchandran             bool assert)
7659b86cd7SDhruvaraj Subhashchandran {
77*3c6f29a0SDhruvaraj Subhashchandran     std::string service;
78*3c6f29a0SDhruvaraj Subhashchandran     try
79*3c6f29a0SDhruvaraj Subhashchandran     {
80*3c6f29a0SDhruvaraj Subhashchandran         service = getService(bus, LED_GROUPS);
81*3c6f29a0SDhruvaraj Subhashchandran     }
82*3c6f29a0SDhruvaraj Subhashchandran     catch (MethodErr& e)
83*3c6f29a0SDhruvaraj Subhashchandran     {
84*3c6f29a0SDhruvaraj Subhashchandran         commit<MethodErr>();
85*3c6f29a0SDhruvaraj Subhashchandran         return;
86*3c6f29a0SDhruvaraj Subhashchandran     }
87*3c6f29a0SDhruvaraj Subhashchandran     catch (ObjectNotFoundErr& e)
88*3c6f29a0SDhruvaraj Subhashchandran     {
89*3c6f29a0SDhruvaraj Subhashchandran         commit<ObjectNotFoundErr>();
90*3c6f29a0SDhruvaraj Subhashchandran         return;
91*3c6f29a0SDhruvaraj Subhashchandran     }
92*3c6f29a0SDhruvaraj Subhashchandran 
93*3c6f29a0SDhruvaraj Subhashchandran     auto pos = path.rfind("/");
94*3c6f29a0SDhruvaraj Subhashchandran     if (pos == std::string::npos)
95*3c6f29a0SDhruvaraj Subhashchandran     {
96*3c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Fru::Monitor;
97*3c6f29a0SDhruvaraj Subhashchandran         report<InventoryPathErr>(
98*3c6f29a0SDhruvaraj Subhashchandran             InventoryPathError::PATH(
99*3c6f29a0SDhruvaraj Subhashchandran                 path.c_str()));
100*3c6f29a0SDhruvaraj Subhashchandran         return;
101*3c6f29a0SDhruvaraj Subhashchandran     }
102*3c6f29a0SDhruvaraj Subhashchandran     auto unit = path.substr(pos + 1);
103*3c6f29a0SDhruvaraj Subhashchandran 
104*3c6f29a0SDhruvaraj Subhashchandran     std::string ledPath = LED_GROUPS +
105*3c6f29a0SDhruvaraj Subhashchandran                           unit + '_' + LED_FAULT;
106*3c6f29a0SDhruvaraj Subhashchandran 
107*3c6f29a0SDhruvaraj Subhashchandran     auto method =  bus.new_method_call(service.c_str(),
108*3c6f29a0SDhruvaraj Subhashchandran                                        ledPath.c_str(),
109*3c6f29a0SDhruvaraj Subhashchandran                                        "org.freedesktop.DBus.Properties",
110*3c6f29a0SDhruvaraj Subhashchandran                                        "Set");
111*3c6f29a0SDhruvaraj Subhashchandran     method.append("xyz.openbmc_project.Led.Group");
112*3c6f29a0SDhruvaraj Subhashchandran     method.append("Asserted");
113*3c6f29a0SDhruvaraj Subhashchandran 
114*3c6f29a0SDhruvaraj Subhashchandran     method.append(sdbusplus::message::variant<bool>(assert));
115*3c6f29a0SDhruvaraj Subhashchandran     bus.call_noreply(method);
116*3c6f29a0SDhruvaraj Subhashchandran 
11759b86cd7SDhruvaraj Subhashchandran     return;
11859b86cd7SDhruvaraj Subhashchandran }
11959b86cd7SDhruvaraj Subhashchandran 
12059b86cd7SDhruvaraj Subhashchandran int Add::created(sd_bus_message* msg,
12159b86cd7SDhruvaraj Subhashchandran                  void* data,
12259b86cd7SDhruvaraj Subhashchandran                  sd_bus_error* retError)
12359b86cd7SDhruvaraj Subhashchandran {
124*3c6f29a0SDhruvaraj Subhashchandran     auto m = sdbusplus::message::message(msg);
125*3c6f29a0SDhruvaraj Subhashchandran     auto bus = m.get_bus();
126*3c6f29a0SDhruvaraj Subhashchandran 
127*3c6f29a0SDhruvaraj Subhashchandran     sdbusplus::message::object_path obPath;
128*3c6f29a0SDhruvaraj Subhashchandran     m.read(obPath);
129*3c6f29a0SDhruvaraj Subhashchandran     std::string objectPath(std::move(obPath));
130*3c6f29a0SDhruvaraj Subhashchandran 
131*3c6f29a0SDhruvaraj Subhashchandran     std::size_t found = objectPath.find(ELOG_ENTRY);
132*3c6f29a0SDhruvaraj Subhashchandran     if (found == std::string::npos)
133*3c6f29a0SDhruvaraj Subhashchandran     {
134*3c6f29a0SDhruvaraj Subhashchandran         //Not a new error entry skip
135*3c6f29a0SDhruvaraj Subhashchandran         return 0;
136*3c6f29a0SDhruvaraj Subhashchandran     }
137*3c6f29a0SDhruvaraj Subhashchandran 
138*3c6f29a0SDhruvaraj Subhashchandran     std::string service;
139*3c6f29a0SDhruvaraj Subhashchandran     try
140*3c6f29a0SDhruvaraj Subhashchandran     {
141*3c6f29a0SDhruvaraj Subhashchandran         service = getService(bus, LOG_PATH);
142*3c6f29a0SDhruvaraj Subhashchandran     }
143*3c6f29a0SDhruvaraj Subhashchandran     catch (MethodErr& e)
144*3c6f29a0SDhruvaraj Subhashchandran     {
145*3c6f29a0SDhruvaraj Subhashchandran         commit<MethodErr>();
146*3c6f29a0SDhruvaraj Subhashchandran         return 0;
147*3c6f29a0SDhruvaraj Subhashchandran     }
148*3c6f29a0SDhruvaraj Subhashchandran     catch (ObjectNotFoundErr& e)
149*3c6f29a0SDhruvaraj Subhashchandran     {
150*3c6f29a0SDhruvaraj Subhashchandran         commit<ObjectNotFoundErr>();
151*3c6f29a0SDhruvaraj Subhashchandran         return 0;
152*3c6f29a0SDhruvaraj Subhashchandran     }
153*3c6f29a0SDhruvaraj Subhashchandran 
154*3c6f29a0SDhruvaraj Subhashchandran     auto method =  bus.new_method_call(service.c_str(), objectPath.c_str(),
155*3c6f29a0SDhruvaraj Subhashchandran                                        "org.freedesktop.DBus.Properties",
156*3c6f29a0SDhruvaraj Subhashchandran                                        "Get");
157*3c6f29a0SDhruvaraj Subhashchandran 
158*3c6f29a0SDhruvaraj Subhashchandran     method.append("org.openbmc.Associations");
159*3c6f29a0SDhruvaraj Subhashchandran     method.append("associations");
160*3c6f29a0SDhruvaraj Subhashchandran     auto reply = bus.call(method);
161*3c6f29a0SDhruvaraj Subhashchandran     if (reply.is_method_error())
162*3c6f29a0SDhruvaraj Subhashchandran     {
163*3c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Fru::Monitor;
164*3c6f29a0SDhruvaraj Subhashchandran         report<AssociationRetrieveErr>(
165*3c6f29a0SDhruvaraj Subhashchandran             AssociationRetrieveError::ELOG_ENTRY_PATH(
166*3c6f29a0SDhruvaraj Subhashchandran                 objectPath.c_str()));
167*3c6f29a0SDhruvaraj Subhashchandran         return 0;
168*3c6f29a0SDhruvaraj Subhashchandran     }
169*3c6f29a0SDhruvaraj Subhashchandran 
170*3c6f29a0SDhruvaraj Subhashchandran     sdbusplus::message::variant<AssociationList> assoc;
171*3c6f29a0SDhruvaraj Subhashchandran     reply.read(assoc);
172*3c6f29a0SDhruvaraj Subhashchandran 
173*3c6f29a0SDhruvaraj Subhashchandran     auto assocs =
174*3c6f29a0SDhruvaraj Subhashchandran         sdbusplus::message::variant_ns::get<AssociationList>(assoc);
175*3c6f29a0SDhruvaraj Subhashchandran     if (assocs.empty())
176*3c6f29a0SDhruvaraj Subhashchandran     {
177*3c6f29a0SDhruvaraj Subhashchandran         //No associations skip
178*3c6f29a0SDhruvaraj Subhashchandran         return 0;
179*3c6f29a0SDhruvaraj Subhashchandran     }
180*3c6f29a0SDhruvaraj Subhashchandran 
181*3c6f29a0SDhruvaraj Subhashchandran     for (const auto& item : assocs)
182*3c6f29a0SDhruvaraj Subhashchandran     {
183*3c6f29a0SDhruvaraj Subhashchandran         if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
184*3c6f29a0SDhruvaraj Subhashchandran         {
185*3c6f29a0SDhruvaraj Subhashchandran             action(bus, std::get<2>(item), true);
186*3c6f29a0SDhruvaraj Subhashchandran             static_cast<Add*>(data)->removeWatches.emplace_back(
187*3c6f29a0SDhruvaraj Subhashchandran                 std::make_unique<Remove>(bus, std::get<2>(item)));
188*3c6f29a0SDhruvaraj Subhashchandran         }
189*3c6f29a0SDhruvaraj Subhashchandran     }
19059b86cd7SDhruvaraj Subhashchandran     return 0;
19159b86cd7SDhruvaraj Subhashchandran }
19259b86cd7SDhruvaraj Subhashchandran 
19359b86cd7SDhruvaraj Subhashchandran int Remove::removed(sd_bus_message* msg,
19459b86cd7SDhruvaraj Subhashchandran                     void* data,
19559b86cd7SDhruvaraj Subhashchandran                     sd_bus_error* retError)
19659b86cd7SDhruvaraj Subhashchandran {
197*3c6f29a0SDhruvaraj Subhashchandran     auto m = sdbusplus::message::message(msg);
198*3c6f29a0SDhruvaraj Subhashchandran     auto bus = m.get_bus();
199*3c6f29a0SDhruvaraj Subhashchandran     std::string assoc;
200*3c6f29a0SDhruvaraj Subhashchandran     m.read(assoc);
201*3c6f29a0SDhruvaraj Subhashchandran 
202*3c6f29a0SDhruvaraj Subhashchandran     if (assoc.compare("org.openbmc.Association"))
203*3c6f29a0SDhruvaraj Subhashchandran     {
204*3c6f29a0SDhruvaraj Subhashchandran         //Skip if not about association
205*3c6f29a0SDhruvaraj Subhashchandran         return 0;
206*3c6f29a0SDhruvaraj Subhashchandran     }
207*3c6f29a0SDhruvaraj Subhashchandran 
208*3c6f29a0SDhruvaraj Subhashchandran     std::map<std::string, std::vector<std::string>> endPoints;
209*3c6f29a0SDhruvaraj Subhashchandran     m.read(endPoints);
210*3c6f29a0SDhruvaraj Subhashchandran     auto it = endPoints.find("endpoints");
211*3c6f29a0SDhruvaraj Subhashchandran 
212*3c6f29a0SDhruvaraj Subhashchandran     if (it == endPoints.end())
213*3c6f29a0SDhruvaraj Subhashchandran     {
214*3c6f29a0SDhruvaraj Subhashchandran         //No end points,skip
215*3c6f29a0SDhruvaraj Subhashchandran         return 0;
216*3c6f29a0SDhruvaraj Subhashchandran     }
217*3c6f29a0SDhruvaraj Subhashchandran 
218*3c6f29a0SDhruvaraj Subhashchandran     if (!((*it).second.empty()))
219*3c6f29a0SDhruvaraj Subhashchandran     {
220*3c6f29a0SDhruvaraj Subhashchandran         //Skip, end points are not empty
221*3c6f29a0SDhruvaraj Subhashchandran         return 0;
222*3c6f29a0SDhruvaraj Subhashchandran     }
223*3c6f29a0SDhruvaraj Subhashchandran 
224*3c6f29a0SDhruvaraj Subhashchandran     action(bus, static_cast<Remove*>(data)->inventoryPath, false);
22559b86cd7SDhruvaraj Subhashchandran     return 0;
22659b86cd7SDhruvaraj Subhashchandran }
22759b86cd7SDhruvaraj Subhashchandran 
22859b86cd7SDhruvaraj Subhashchandran }//namespace monitor
22959b86cd7SDhruvaraj Subhashchandran }//namespace fault
23059b86cd7SDhruvaraj Subhashchandran }//namespace fru
23159b86cd7SDhruvaraj Subhashchandran }//namespace led
23259b86cd7SDhruvaraj Subhashchandran }//namespace phosphor
233