1 #pragma once
2 
3 #include "dump_manager.hpp"
4 
5 #include <fmt/core.h>
6 #include <systemd/sd-event.h>
7 #include <unistd.h>
8 
9 #include <com/ibm/Dump/Create/server.hpp>
10 #include <phosphor-logging/elog-errors.hpp>
11 #include <phosphor-logging/elog.hpp>
12 #include <sdbusplus/bus.hpp>
13 #include <xyz/openbmc_project/Common/error.hpp>
14 #include <xyz/openbmc_project/Dump/Create/server.hpp>
15 #include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
16 
17 #include <memory>
18 
19 namespace phosphor
20 {
21 namespace dump
22 {
23 
24 using BootProgress = sdbusplus::xyz::openbmc_project::State::Boot::server::
25     Progress::ProgressStages;
26 
27 using namespace phosphor::logging;
28 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
29 
30 /* Need a custom deleter for freeing up sd_event */
31 struct EventDeleter
32 {
33     void operator()(sd_event* event) const
34     {
35         event = sd_event_unref(event);
36     }
37 };
38 using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
39 
40 /** @struct CustomFd
41  *
42  *  RAII wrapper for file descriptor.
43  */
44 struct CustomFd
45 {
46   private:
47     /** @brief File descriptor */
48     int fd = -1;
49 
50   public:
51     CustomFd() = delete;
52     CustomFd(const CustomFd&) = delete;
53     CustomFd& operator=(const CustomFd&) = delete;
54     CustomFd(CustomFd&&) = delete;
55     CustomFd& operator=(CustomFd&&) = delete;
56 
57     /** @brief Saves File descriptor and uses it to do file operation
58      *
59      *  @param[in] fd - File descriptor
60      */
61     CustomFd(int fd) : fd(fd)
62     {}
63 
64     ~CustomFd()
65     {
66         if (fd >= 0)
67         {
68             close(fd);
69         }
70     }
71 
72     int operator()() const
73     {
74         return fd;
75     }
76 };
77 
78 /**
79  * @brief Get the bus service
80  *
81  * @param[in] bus - Bus to attach to.
82  * @param[in] path - D-Bus path name.
83  * @param[in] interface - D-Bus interface name.
84  * @return the bus service as a string
85  **/
86 std::string getService(sdbusplus::bus_t& bus, const std::string& path,
87                        const std::string& interface);
88 
89 /**
90  * @brief Get the host boot progress stage
91  *
92  * @return BootProgress on success
93  *         Throw exception on failure
94  *
95  */
96 BootProgress getBootProgress();
97 
98 /**
99  * @brief Check whether host is running
100  *
101  * @return true if the host running else false.
102  *         Throw exception on failure.
103  */
104 bool isHostRunning();
105 
106 inline void extractOriginatorProperties(phosphor::dump::DumpCreateParams params,
107                                         std::string& originatorId,
108                                         originatorTypes& originatorType)
109 {
110     using InvalidArgument =
111         sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
112     using Argument = xyz::openbmc_project::Common::InvalidArgument;
113     using CreateParametersXYZ =
114         sdbusplus::xyz::openbmc_project::Dump::server::Create::CreateParameters;
115 
116     auto iter = params.find(
117         sdbusplus::xyz::openbmc_project::Dump::server::Create::
118             convertCreateParametersToString(CreateParametersXYZ::OriginatorId));
119     if (iter == params.end())
120     {
121         log<level::INFO>("OriginatorId is not provided");
122     }
123     else
124     {
125         try
126         {
127             originatorId = std::get<std::string>(iter->second);
128         }
129         catch (const std::bad_variant_access& e)
130         {
131             // Exception will be raised if the input is not string
132             log<level::ERR>(
133                 fmt::format(
134                     "An invalid  originatorId passed. It should be a string, "
135                     "errormsg({})",
136                     e.what())
137                     .c_str());
138             elog<InvalidArgument>(Argument::ARGUMENT_NAME("ORIGINATOR_ID"),
139                                   Argument::ARGUMENT_VALUE("INVALID INPUT"));
140         }
141     }
142 
143     iter = params.find(sdbusplus::xyz::openbmc_project::Dump::server::Create::
144                            convertCreateParametersToString(
145                                CreateParametersXYZ::OriginatorType));
146     if (iter == params.end())
147     {
148         log<level::INFO>("OriginatorType is not provided. Replacing the string "
149                          "with the default value");
150         originatorType = originatorTypes::Internal;
151     }
152     else
153     {
154         try
155         {
156             std::string type = std::get<std::string>(iter->second);
157             originatorType = sdbusplus::xyz::openbmc_project::Common::server::
158                 OriginatedBy::convertOriginatorTypesFromString(type);
159         }
160         catch (const std::bad_variant_access& e)
161         {
162             // Exception will be raised if the input is not string
163             log<level::ERR>(fmt::format("An invalid originatorType passed, "
164                                         "errormsg({})",
165                                         e.what())
166                                 .c_str());
167             elog<InvalidArgument>(Argument::ARGUMENT_NAME("ORIGINATOR_TYPE"),
168                                   Argument::ARGUMENT_VALUE("INVALID INPUT"));
169         }
170     }
171 }
172 
173 } // namespace dump
174 } // namespace phosphor
175