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 <org/open_power/Witherspoon/Fault/error.hpp>
17 #include "elog-errors.hpp"
18 #include "utility.hpp"
19 
20 namespace witherspoon
21 {
22 namespace power
23 {
24 namespace util
25 {
26 
27 constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
28 constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
29 constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
30 constexpr auto SYSTEMD_SERVICE   = "org.freedesktop.systemd1";
31 constexpr auto SYSTEMD_ROOT      = "/org/freedesktop/systemd1";
32 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
33 constexpr auto POWEROFF_TARGET   = "obmc-chassis-hard-poweroff@0.target";
34 
35 using namespace phosphor::logging;
36 using namespace sdbusplus::org::open_power::Witherspoon::Fault::Error;
37 
38 
39 std::string getService(const std::string& path,
40                        const std::string& interface,
41                        sdbusplus::bus::bus& bus)
42 {
43     auto method = bus.new_method_call(MAPPER_BUSNAME,
44             MAPPER_PATH,
45             MAPPER_INTERFACE,
46             "GetObject");
47 
48     method.append(path);
49     method.append(std::vector<std::string>({interface}));
50 
51     auto reply = bus.call(method);
52     if (reply.is_method_error())
53     {
54         log<level::ERR>("Error in mapper call to get service name",
55                 entry("PATH=%s", path.c_str()),
56                 entry("INTERFACE=%s", interface.c_str()));
57 
58         // TODO openbmc/openbmc#851 - Once available, throw returned error
59         throw std::runtime_error("Error in mapper call to get service name");
60     }
61 
62     std::map<std::string, std::vector<std::string>> response;
63     reply.read(response);
64 
65     if (response.empty())
66     {
67         log<level::ERR>(
68                 "Error in mapper response for getting service name",
69                 entry("PATH=%s", path.c_str()),
70                 entry("INTERFACE=%s", interface.c_str()));
71         return std::string{};
72     }
73 
74     return response.begin()->first;
75 }
76 
77 
78 void powerOff(sdbusplus::bus::bus& bus)
79 {
80     log<level::INFO>("Powering off due to a power fault");
81     report<Shutdown>();
82 
83     auto method = bus.new_method_call(SYSTEMD_SERVICE,
84             SYSTEMD_ROOT,
85             SYSTEMD_INTERFACE,
86             "StartUnit");
87 
88     method.append(POWEROFF_TARGET);
89     method.append("replace");
90 
91     bus.call_noreply(method);
92 }
93 
94 
95 }
96 }
97 }
98