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