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 {
operator ()(sdbusplus::bus_t & bus,sdbusplus::message_t &,Manager & mgr) const33 bool PropertyConditionBase::operator()(
34     sdbusplus::bus_t& bus, sdbusplus::message_t&, Manager& mgr) const
35 {
36     std::string path(_path);
37     return (*this)(path, bus, mgr);
38 }
39 
operator ()(const std::string & path,sdbusplus::bus_t & bus,Manager & mgr) const40 bool PropertyConditionBase::operator()(
41     const std::string& path, sdbusplus::bus_t& bus, Manager& mgr) const
42 {
43     std::string host;
44 
45     if (_service)
46     {
47         host.assign(_service);
48     }
49     else
50     {
51         auto mapperCall = bus.new_method_call(
52             "xyz.openbmc_project.ObjectMapper",
53             "/xyz/openbmc_project/object_mapper",
54             "xyz.openbmc_project.ObjectMapper", "GetObject");
55         mapperCall.append(path);
56         mapperCall.append(std::vector<std::string>({_iface}));
57 
58         std::map<std::string, std::vector<std::string>> mapperResponse;
59         try
60         {
61             auto mapperResponseMsg = bus.call(mapperCall);
62             mapperResponseMsg.read(mapperResponse);
63         }
64         catch (const std::exception& e)
65         {
66             lg2::error("Failed to execute GetObject method: {ERROR}", "ERROR",
67                        e);
68             return false;
69         }
70 
71         if (mapperResponse.empty())
72         {
73             return false;
74         }
75 
76         host = mapperResponse.begin()->first;
77     }
78 
79     // When the host service name is inventory manager, eval using
80     // a given `getProperty` function to retrieve a property value from
81     // an interface hosted by inventory manager.
82     if (host == BUSNAME)
83     {
84         try
85         {
86             return eval(mgr);
87         }
88         catch (const std::exception& e)
89         {
90             // Unable to find property on inventory manager,
91             // default condition to false.
92             return false;
93         }
94     }
95 
96     auto hostCall = bus.new_method_call(
97         host.c_str(), path.c_str(), "org.freedesktop.DBus.Properties", "Get");
98     hostCall.append(_iface);
99     hostCall.append(_property);
100 
101     try
102     {
103         auto hostResponseMsg = bus.call(hostCall);
104         return eval(hostResponseMsg);
105     }
106     catch (const std::exception& e)
107     {
108         lg2::error("Failed to execute Get method: {ERROR}", "ERROR", e);
109         return false;
110     }
111 }
112 
113 } // namespace functor
114 } // namespace manager
115 } // namespace inventory
116 } // namespace phosphor
117 
118 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
119