1 /**
2  * Copyright © 2017 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "config.h"
17 
18 #include "functor.hpp"
19 
20 #include "manager.hpp"
21 
22 #include <phosphor-logging/lg2.hpp>
23 #include <sdbusplus/bus.hpp>
24 
25 namespace phosphor
26 {
27 namespace inventory
28 {
29 namespace manager
30 {
31 namespace functor
32 {
33 bool PropertyConditionBase::operator()(sdbusplus::bus_t& bus,
34                                        sdbusplus::message_t&,
35                                        Manager& mgr) const
36 {
37     std::string path(_path);
38     return (*this)(path, bus, mgr);
39 }
40 
41 bool PropertyConditionBase::operator()(const std::string& path,
42                                        sdbusplus::bus_t& bus,
43                                        Manager& mgr) const
44 {
45     std::string host;
46 
47     if (_service)
48     {
49         host.assign(_service);
50     }
51     else
52     {
53         auto mapperCall = bus.new_method_call(
54             "xyz.openbmc_project.ObjectMapper",
55             "/xyz/openbmc_project/object_mapper",
56             "xyz.openbmc_project.ObjectMapper", "GetObject");
57         mapperCall.append(path);
58         mapperCall.append(std::vector<std::string>({_iface}));
59 
60         std::map<std::string, std::vector<std::string>> mapperResponse;
61         try
62         {
63             auto mapperResponseMsg = bus.call(mapperCall);
64             mapperResponseMsg.read(mapperResponse);
65         }
66         catch (const std::exception& e)
67         {
68             lg2::error("Failed to execute GetObject method: {ERROR}", "ERROR",
69                        e);
70             return false;
71         }
72 
73         if (mapperResponse.empty())
74         {
75             return false;
76         }
77 
78         host = mapperResponse.begin()->first;
79     }
80 
81     // When the host service name is inventory manager, eval using
82     // a given `getProperty` function to retrieve a property value from
83     // an interface hosted by inventory manager.
84     if (host == BUSNAME)
85     {
86         try
87         {
88             return eval(mgr);
89         }
90         catch (const std::exception& e)
91         {
92             // Unable to find property on inventory manager,
93             // default condition to false.
94             return false;
95         }
96     }
97 
98     auto hostCall = bus.new_method_call(
99         host.c_str(), path.c_str(), "org.freedesktop.DBus.Properties", "Get");
100     hostCall.append(_iface);
101     hostCall.append(_property);
102 
103     try
104     {
105         auto hostResponseMsg = bus.call(hostCall);
106         return eval(hostResponseMsg);
107     }
108     catch (const std::exception& e)
109     {
110         lg2::error("Failed to execute Get method: {ERROR}", "ERROR", e);
111         return false;
112     }
113 }
114 
115 } // namespace functor
116 } // namespace manager
117 } // namespace inventory
118 } // namespace phosphor
119 
120 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
121