xref: /openbmc/bmcweb/features/redfish/lib/virtual_media.hpp (revision d04ba325f3ef4e60eb4fd8e7477af78d1be0d79d)
1107077deSPrzemyslaw Czarnowski /*
2107077deSPrzemyslaw Czarnowski // Copyright (c) 2018 Intel Corporation
3107077deSPrzemyslaw Czarnowski //
4107077deSPrzemyslaw Czarnowski // Licensed under the Apache License, Version 2.0 (the "License");
5107077deSPrzemyslaw Czarnowski // you may not use this file except in compliance with the License.
6107077deSPrzemyslaw Czarnowski // You may obtain a copy of the License at
7107077deSPrzemyslaw Czarnowski //
8107077deSPrzemyslaw Czarnowski //      http://www.apache.org/licenses/LICENSE-2.0
9107077deSPrzemyslaw Czarnowski //
10107077deSPrzemyslaw Czarnowski // Unless required by applicable law or agreed to in writing, software
11107077deSPrzemyslaw Czarnowski // distributed under the License is distributed on an "AS IS" BASIS,
12107077deSPrzemyslaw Czarnowski // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13107077deSPrzemyslaw Czarnowski // See the License for the specific language governing permissions and
14107077deSPrzemyslaw Czarnowski // limitations under the License.
15107077deSPrzemyslaw Czarnowski */
16107077deSPrzemyslaw Czarnowski #pragma once
17107077deSPrzemyslaw Czarnowski 
18107077deSPrzemyslaw Czarnowski #include <boost/container/flat_map.hpp>
19107077deSPrzemyslaw Czarnowski #include <node.hpp>
20107077deSPrzemyslaw Czarnowski #include <utils/json_utils.hpp>
21107077deSPrzemyslaw Czarnowski // for GetObjectType and ManagedObjectType
22e13c2760SPrzemyslaw Czarnowski #include <account_service.hpp>
23107077deSPrzemyslaw Czarnowski 
24107077deSPrzemyslaw Czarnowski namespace redfish
25107077deSPrzemyslaw Czarnowski 
26107077deSPrzemyslaw Czarnowski {
27107077deSPrzemyslaw Czarnowski 
28107077deSPrzemyslaw Czarnowski /**
29107077deSPrzemyslaw Czarnowski  * @brief Read all known properties from VM object interfaces
30107077deSPrzemyslaw Czarnowski  */
31107077deSPrzemyslaw Czarnowski static void vmParseInterfaceObject(const DbusInterfaceType &interface,
32107077deSPrzemyslaw Czarnowski                                    std::shared_ptr<AsyncResp> aResp)
33107077deSPrzemyslaw Czarnowski {
34107077deSPrzemyslaw Czarnowski     const auto mountPointIface =
35107077deSPrzemyslaw Czarnowski         interface.find("xyz.openbmc_project.VirtualMedia.MountPoint");
36107077deSPrzemyslaw Czarnowski     if (mountPointIface == interface.cend())
37107077deSPrzemyslaw Czarnowski     {
38107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Interface MountPoint not found";
39107077deSPrzemyslaw Czarnowski         return;
40107077deSPrzemyslaw Czarnowski     }
41107077deSPrzemyslaw Czarnowski 
42107077deSPrzemyslaw Czarnowski     const auto processIface =
43107077deSPrzemyslaw Czarnowski         interface.find("xyz.openbmc_project.VirtualMedia.Process");
44107077deSPrzemyslaw Czarnowski     if (processIface == interface.cend())
45107077deSPrzemyslaw Czarnowski     {
46107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Interface Process not found";
47107077deSPrzemyslaw Czarnowski         return;
48107077deSPrzemyslaw Czarnowski     }
49107077deSPrzemyslaw Czarnowski 
50107077deSPrzemyslaw Czarnowski     const auto endpointIdProperty = mountPointIface->second.find("EndpointId");
51107077deSPrzemyslaw Czarnowski     if (endpointIdProperty == mountPointIface->second.cend())
52107077deSPrzemyslaw Czarnowski     {
53107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Property EndpointId not found";
54107077deSPrzemyslaw Czarnowski         return;
55107077deSPrzemyslaw Czarnowski     }
56107077deSPrzemyslaw Czarnowski 
57107077deSPrzemyslaw Czarnowski     const auto activeProperty = processIface->second.find("Active");
58107077deSPrzemyslaw Czarnowski     if (activeProperty == processIface->second.cend())
59107077deSPrzemyslaw Czarnowski     {
60107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Property Active not found";
61107077deSPrzemyslaw Czarnowski         return;
62107077deSPrzemyslaw Czarnowski     }
63107077deSPrzemyslaw Czarnowski 
64107077deSPrzemyslaw Czarnowski     const bool *activeValue = std::get_if<bool>(&activeProperty->second);
65107077deSPrzemyslaw Czarnowski     if (!activeValue)
66107077deSPrzemyslaw Czarnowski     {
67107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Value Active not found";
68107077deSPrzemyslaw Czarnowski         return;
69107077deSPrzemyslaw Czarnowski     }
70107077deSPrzemyslaw Czarnowski 
71107077deSPrzemyslaw Czarnowski     const std::string *endpointIdValue =
72107077deSPrzemyslaw Czarnowski         std::get_if<std::string>(&endpointIdProperty->second);
73107077deSPrzemyslaw Czarnowski     if (endpointIdValue)
74107077deSPrzemyslaw Czarnowski     {
75107077deSPrzemyslaw Czarnowski         if (!endpointIdValue->empty())
76107077deSPrzemyslaw Czarnowski         {
77107077deSPrzemyslaw Czarnowski             // Proxy mode
78*d04ba325SPrzemyslaw Czarnowski             aResp->res.jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
79*d04ba325SPrzemyslaw Czarnowski                 *endpointIdValue;
80107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["TransferProtocolType"] = "OEM";
81107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["Inserted"] = *activeValue;
82107077deSPrzemyslaw Czarnowski             if (*activeValue == true)
83107077deSPrzemyslaw Czarnowski             {
84107077deSPrzemyslaw Czarnowski                 aResp->res.jsonValue["ConnectedVia"] = "Applet";
85107077deSPrzemyslaw Czarnowski             }
86107077deSPrzemyslaw Czarnowski         }
87107077deSPrzemyslaw Czarnowski         else
88107077deSPrzemyslaw Czarnowski         {
89107077deSPrzemyslaw Czarnowski             // Legacy mode
90107077deSPrzemyslaw Czarnowski             const auto imageUrlProperty =
91107077deSPrzemyslaw Czarnowski                 mountPointIface->second.find("ImageURL");
92107077deSPrzemyslaw Czarnowski             if (imageUrlProperty != processIface->second.cend())
93107077deSPrzemyslaw Czarnowski             {
94107077deSPrzemyslaw Czarnowski                 const std::string *imageUrlValue =
95107077deSPrzemyslaw Czarnowski                     std::get_if<std::string>(&imageUrlProperty->second);
96107077deSPrzemyslaw Czarnowski                 if (imageUrlValue && !imageUrlValue->empty())
97107077deSPrzemyslaw Czarnowski                 {
98107077deSPrzemyslaw Czarnowski                     aResp->res.jsonValue["ImageName"] = *imageUrlValue;
99107077deSPrzemyslaw Czarnowski                     aResp->res.jsonValue["Inserted"] = *activeValue;
100107077deSPrzemyslaw Czarnowski                     if (*activeValue == true)
101107077deSPrzemyslaw Czarnowski                     {
102107077deSPrzemyslaw Czarnowski                         aResp->res.jsonValue["ConnectedVia"] = "URI";
103107077deSPrzemyslaw Czarnowski                     }
104107077deSPrzemyslaw Czarnowski                 }
105107077deSPrzemyslaw Czarnowski             }
106107077deSPrzemyslaw Czarnowski         }
107107077deSPrzemyslaw Czarnowski     }
108107077deSPrzemyslaw Czarnowski }
109107077deSPrzemyslaw Czarnowski 
110107077deSPrzemyslaw Czarnowski /**
111107077deSPrzemyslaw Czarnowski  * @brief Fill template for Virtual Media Item.
112107077deSPrzemyslaw Czarnowski  */
113107077deSPrzemyslaw Czarnowski static nlohmann::json vmItemTemplate(const std::string &name,
114107077deSPrzemyslaw Czarnowski                                      const std::string &resName)
115107077deSPrzemyslaw Czarnowski {
116107077deSPrzemyslaw Czarnowski     nlohmann::json item;
117107077deSPrzemyslaw Czarnowski     item["@odata.id"] =
118107077deSPrzemyslaw Czarnowski         "/redfish/v1/Managers/" + name + "/VirtualMedia/" + resName;
119*d04ba325SPrzemyslaw Czarnowski     item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
120107077deSPrzemyslaw Czarnowski     item["@odata.context"] = "/redfish/v1/$metadata#VirtualMedia.VirtualMedia";
121107077deSPrzemyslaw Czarnowski     item["Name"] = "Virtual Removable Media";
122107077deSPrzemyslaw Czarnowski     item["Id"] = resName;
123107077deSPrzemyslaw Czarnowski     item["Image"] = nullptr;
124107077deSPrzemyslaw Czarnowski     item["Inserted"] = nullptr;
125107077deSPrzemyslaw Czarnowski     item["ImageName"] = nullptr;
126107077deSPrzemyslaw Czarnowski     item["WriteProtected"] = true;
127107077deSPrzemyslaw Czarnowski     item["ConnectedVia"] = "NotConnected";
128107077deSPrzemyslaw Czarnowski     item["MediaTypes"] = {"CD", "USBStick"};
129107077deSPrzemyslaw Czarnowski     item["TransferMethod"] = "Stream";
130107077deSPrzemyslaw Czarnowski     item["TransferProtocolType"] = nullptr;
131*d04ba325SPrzemyslaw Czarnowski     item["Oem"]["OpenBmc"]["WebSocketEndpoint"] = nullptr;
132*d04ba325SPrzemyslaw Czarnowski     item["Oem"]["OpenBMC"]["@odata.type"] =
133*d04ba325SPrzemyslaw Czarnowski         "#OemVirtualMedia.v1_0_0.VirtualMedia";
134107077deSPrzemyslaw Czarnowski 
135107077deSPrzemyslaw Czarnowski     return item;
136107077deSPrzemyslaw Czarnowski }
137107077deSPrzemyslaw Czarnowski 
138107077deSPrzemyslaw Czarnowski /**
139107077deSPrzemyslaw Czarnowski  *  @brief Fills collection data
140107077deSPrzemyslaw Czarnowski  */
141107077deSPrzemyslaw Czarnowski static void getVmResourceList(std::shared_ptr<AsyncResp> aResp,
142107077deSPrzemyslaw Czarnowski                               const std::string &service,
143107077deSPrzemyslaw Czarnowski                               const std::string &name)
144107077deSPrzemyslaw Czarnowski {
145107077deSPrzemyslaw Czarnowski     BMCWEB_LOG_DEBUG << "Get available Virtual Media resources.";
146107077deSPrzemyslaw Czarnowski     crow::connections::systemBus->async_method_call(
147107077deSPrzemyslaw Czarnowski         [name, aResp{std::move(aResp)}](const boost::system::error_code ec,
148107077deSPrzemyslaw Czarnowski                                         ManagedObjectType &subtree) {
149107077deSPrzemyslaw Czarnowski             if (ec)
150107077deSPrzemyslaw Czarnowski             {
151107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "DBUS response error";
152107077deSPrzemyslaw Czarnowski                 return;
153107077deSPrzemyslaw Czarnowski             }
154107077deSPrzemyslaw Czarnowski             nlohmann::json &members = aResp->res.jsonValue["Members"];
155107077deSPrzemyslaw Czarnowski             members = nlohmann::json::array();
156107077deSPrzemyslaw Czarnowski 
157107077deSPrzemyslaw Czarnowski             for (const auto &object : subtree)
158107077deSPrzemyslaw Czarnowski             {
159107077deSPrzemyslaw Czarnowski                 nlohmann::json item;
160107077deSPrzemyslaw Czarnowski                 const std::string &path =
161107077deSPrzemyslaw Czarnowski                     static_cast<const std::string &>(object.first);
162107077deSPrzemyslaw Czarnowski                 std::size_t lastIndex = path.rfind("/");
163107077deSPrzemyslaw Czarnowski                 if (lastIndex == std::string::npos)
164107077deSPrzemyslaw Czarnowski                 {
165107077deSPrzemyslaw Czarnowski                     continue;
166107077deSPrzemyslaw Czarnowski                 }
167107077deSPrzemyslaw Czarnowski 
168107077deSPrzemyslaw Czarnowski                 lastIndex += 1;
169107077deSPrzemyslaw Czarnowski 
170107077deSPrzemyslaw Czarnowski                 item["@odata.id"] = "/redfish/v1/Managers/" + name +
171107077deSPrzemyslaw Czarnowski                                     "/VirtualMedia/" + path.substr(lastIndex);
172107077deSPrzemyslaw Czarnowski 
173107077deSPrzemyslaw Czarnowski                 members.emplace_back(std::move(item));
174107077deSPrzemyslaw Czarnowski             }
175107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["Members@odata.count"] = members.size();
176107077deSPrzemyslaw Czarnowski         },
177107077deSPrzemyslaw Czarnowski         service, "/xyz/openbmc_project/VirtualMedia",
178107077deSPrzemyslaw Czarnowski         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
179107077deSPrzemyslaw Czarnowski }
180107077deSPrzemyslaw Czarnowski 
181107077deSPrzemyslaw Czarnowski /**
182107077deSPrzemyslaw Czarnowski  *  @brief Fills data for specific resource
183107077deSPrzemyslaw Czarnowski  */
184107077deSPrzemyslaw Czarnowski static void getVmData(std::shared_ptr<AsyncResp> aResp,
185107077deSPrzemyslaw Czarnowski                       const std::string &service, const std::string &name,
186107077deSPrzemyslaw Czarnowski                       const std::string &resName)
187107077deSPrzemyslaw Czarnowski {
188107077deSPrzemyslaw Czarnowski     BMCWEB_LOG_DEBUG << "Get Virtual Media resource data.";
189107077deSPrzemyslaw Czarnowski 
190107077deSPrzemyslaw Czarnowski     crow::connections::systemBus->async_method_call(
191107077deSPrzemyslaw Czarnowski         [resName, name, aResp](const boost::system::error_code ec,
192107077deSPrzemyslaw Czarnowski                                ManagedObjectType &subtree) {
193107077deSPrzemyslaw Czarnowski             if (ec)
194107077deSPrzemyslaw Czarnowski             {
195107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "DBUS response error";
196e13c2760SPrzemyslaw Czarnowski 
197107077deSPrzemyslaw Czarnowski                 return;
198107077deSPrzemyslaw Czarnowski             }
199107077deSPrzemyslaw Czarnowski 
200107077deSPrzemyslaw Czarnowski             for (auto &item : subtree)
201107077deSPrzemyslaw Czarnowski             {
202107077deSPrzemyslaw Czarnowski                 const std::string &path =
203107077deSPrzemyslaw Czarnowski                     static_cast<const std::string &>(item.first);
204107077deSPrzemyslaw Czarnowski 
205107077deSPrzemyslaw Czarnowski                 std::size_t lastItem = path.rfind("/");
206107077deSPrzemyslaw Czarnowski                 if (lastItem == std::string::npos)
207107077deSPrzemyslaw Czarnowski                 {
208107077deSPrzemyslaw Czarnowski                     continue;
209107077deSPrzemyslaw Czarnowski                 }
210107077deSPrzemyslaw Czarnowski 
211107077deSPrzemyslaw Czarnowski                 if (path.substr(lastItem + 1) != resName)
212107077deSPrzemyslaw Czarnowski                 {
213107077deSPrzemyslaw Czarnowski                     continue;
214107077deSPrzemyslaw Czarnowski                 }
215107077deSPrzemyslaw Czarnowski 
216107077deSPrzemyslaw Czarnowski                 aResp->res.jsonValue = vmItemTemplate(name, resName);
217107077deSPrzemyslaw Czarnowski 
218e13c2760SPrzemyslaw Czarnowski                 // Check if dbus path is Legacy type
219e13c2760SPrzemyslaw Czarnowski                 if (path.find("VirtualMedia/Legacy") != std::string::npos)
220e13c2760SPrzemyslaw Czarnowski                 {
221e13c2760SPrzemyslaw Czarnowski                     aResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
222e13c2760SPrzemyslaw Czarnowski                                         ["target"] =
223e13c2760SPrzemyslaw Czarnowski                         "/redfish/v1/Managers/" + name + "/VirtualMedia/" +
224e13c2760SPrzemyslaw Czarnowski                         resName + "/Actions/VirtualMedia.InsertMedia";
225e13c2760SPrzemyslaw Czarnowski                 }
226e13c2760SPrzemyslaw Czarnowski 
227107077deSPrzemyslaw Czarnowski                 vmParseInterfaceObject(item.second, aResp);
228107077deSPrzemyslaw Czarnowski 
229e13c2760SPrzemyslaw Czarnowski                 aResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
230e13c2760SPrzemyslaw Czarnowski                                     ["target"] =
231e13c2760SPrzemyslaw Czarnowski                     "/redfish/v1/Managers/" + name + "/VirtualMedia/" +
232e13c2760SPrzemyslaw Czarnowski                     resName + "/Actions/VirtualMedia.EjectMedia";
233e13c2760SPrzemyslaw Czarnowski 
234107077deSPrzemyslaw Czarnowski                 return;
235107077deSPrzemyslaw Czarnowski             }
236107077deSPrzemyslaw Czarnowski 
237107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(
238*d04ba325SPrzemyslaw Czarnowski                 aResp->res, "#VirtualMedia.v1_3_0.VirtualMedia", resName);
239107077deSPrzemyslaw Czarnowski         },
240107077deSPrzemyslaw Czarnowski         service, "/xyz/openbmc_project/VirtualMedia",
241107077deSPrzemyslaw Czarnowski         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
242107077deSPrzemyslaw Czarnowski }
243107077deSPrzemyslaw Czarnowski 
244e13c2760SPrzemyslaw Czarnowski /**
245e13c2760SPrzemyslaw Czarnowski    @brief InsertMedia action class
246e13c2760SPrzemyslaw Czarnowski  */
247e13c2760SPrzemyslaw Czarnowski class VirtualMediaActionInsertMedia : public Node
248e13c2760SPrzemyslaw Czarnowski {
249e13c2760SPrzemyslaw Czarnowski   public:
250e13c2760SPrzemyslaw Czarnowski     VirtualMediaActionInsertMedia(CrowApp &app) :
251e13c2760SPrzemyslaw Czarnowski         Node(app,
252e13c2760SPrzemyslaw Czarnowski              "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
253e13c2760SPrzemyslaw Czarnowski              "VirtualMedia.InsertMedia",
254e13c2760SPrzemyslaw Czarnowski              std::string(), std::string())
255e13c2760SPrzemyslaw Czarnowski     {
256e13c2760SPrzemyslaw Czarnowski         entityPrivileges = {
257e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
258e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
259e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
260e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
261e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
262e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
263e13c2760SPrzemyslaw Czarnowski     }
264e13c2760SPrzemyslaw Czarnowski 
265e13c2760SPrzemyslaw Czarnowski   private:
266e13c2760SPrzemyslaw Czarnowski     /**
267e13c2760SPrzemyslaw Czarnowski      * @brief Function handles POST method request.
268e13c2760SPrzemyslaw Czarnowski      *
269e13c2760SPrzemyslaw Czarnowski      * Analyzes POST body message before sends Reset request data to dbus.
270e13c2760SPrzemyslaw Czarnowski      */
271e13c2760SPrzemyslaw Czarnowski     void doPost(crow::Response &res, const crow::Request &req,
272e13c2760SPrzemyslaw Czarnowski                 const std::vector<std::string> &params) override
273e13c2760SPrzemyslaw Czarnowski     {
274e13c2760SPrzemyslaw Czarnowski         auto aResp = std::make_shared<AsyncResp>(res);
275e13c2760SPrzemyslaw Czarnowski 
276e13c2760SPrzemyslaw Czarnowski         if (params.size() != 2)
277e13c2760SPrzemyslaw Czarnowski         {
278e13c2760SPrzemyslaw Czarnowski             messages::internalError(res);
279e13c2760SPrzemyslaw Czarnowski             return;
280e13c2760SPrzemyslaw Czarnowski         }
281e13c2760SPrzemyslaw Czarnowski 
282e13c2760SPrzemyslaw Czarnowski         // take resource name from URL
283e13c2760SPrzemyslaw Czarnowski         const std::string &resName = params[1];
284e13c2760SPrzemyslaw Czarnowski 
285e13c2760SPrzemyslaw Czarnowski         if (params[0] != "bmc")
286e13c2760SPrzemyslaw Czarnowski         {
287e13c2760SPrzemyslaw Czarnowski             messages::resourceNotFound(res, "VirtualMedia.Insert", resName);
288e13c2760SPrzemyslaw Czarnowski 
289e13c2760SPrzemyslaw Czarnowski             return;
290e13c2760SPrzemyslaw Czarnowski         }
291e13c2760SPrzemyslaw Czarnowski 
292e13c2760SPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
293e13c2760SPrzemyslaw Czarnowski             [this, aResp{std::move(aResp)}, req,
294e13c2760SPrzemyslaw Czarnowski              resName](const boost::system::error_code ec,
295e13c2760SPrzemyslaw Czarnowski                       const GetObjectType &getObjectType) {
296e13c2760SPrzemyslaw Czarnowski                 if (ec)
297e13c2760SPrzemyslaw Czarnowski                 {
298e13c2760SPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
299e13c2760SPrzemyslaw Czarnowski                                      << ec;
300e13c2760SPrzemyslaw Czarnowski                     messages::internalError(aResp->res);
301e13c2760SPrzemyslaw Czarnowski 
302e13c2760SPrzemyslaw Czarnowski                     return;
303e13c2760SPrzemyslaw Czarnowski                 }
304e13c2760SPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
305e13c2760SPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
306e13c2760SPrzemyslaw Czarnowski 
307e13c2760SPrzemyslaw Czarnowski                 crow::connections::systemBus->async_method_call(
308e13c2760SPrzemyslaw Czarnowski                     [this, service, resName, req, aResp{std::move(aResp)}](
309e13c2760SPrzemyslaw Czarnowski                         const boost::system::error_code ec,
310e13c2760SPrzemyslaw Czarnowski                         ManagedObjectType &subtree) {
311e13c2760SPrzemyslaw Czarnowski                         if (ec)
312e13c2760SPrzemyslaw Czarnowski                         {
313e13c2760SPrzemyslaw Czarnowski                             BMCWEB_LOG_DEBUG << "DBUS response error";
314e13c2760SPrzemyslaw Czarnowski 
315e13c2760SPrzemyslaw Czarnowski                             return;
316e13c2760SPrzemyslaw Czarnowski                         }
317e13c2760SPrzemyslaw Czarnowski 
318e13c2760SPrzemyslaw Czarnowski                         for (const auto &object : subtree)
319e13c2760SPrzemyslaw Czarnowski                         {
320e13c2760SPrzemyslaw Czarnowski                             const std::string &path =
321e13c2760SPrzemyslaw Czarnowski                                 static_cast<const std::string &>(object.first);
322e13c2760SPrzemyslaw Czarnowski 
323e13c2760SPrzemyslaw Czarnowski                             std::size_t lastIndex = path.rfind("/");
324e13c2760SPrzemyslaw Czarnowski                             if (lastIndex == std::string::npos)
325e13c2760SPrzemyslaw Czarnowski                             {
326e13c2760SPrzemyslaw Czarnowski                                 continue;
327e13c2760SPrzemyslaw Czarnowski                             }
328e13c2760SPrzemyslaw Czarnowski 
329e13c2760SPrzemyslaw Czarnowski                             lastIndex += 1;
330e13c2760SPrzemyslaw Czarnowski 
331e13c2760SPrzemyslaw Czarnowski                             if (path.substr(lastIndex) == resName)
332e13c2760SPrzemyslaw Czarnowski                             {
333e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Proxy");
334e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
335e13c2760SPrzemyslaw Czarnowski                                 {
336e13c2760SPrzemyslaw Czarnowski                                     // Not possible in proxy mode
337e13c2760SPrzemyslaw Czarnowski                                     BMCWEB_LOG_DEBUG << "InsertMedia not "
338e13c2760SPrzemyslaw Czarnowski                                                         "allowed in proxy mode";
339e13c2760SPrzemyslaw Czarnowski                                     messages::resourceNotFound(
340e13c2760SPrzemyslaw Czarnowski                                         aResp->res, "VirtualMedia.InsertMedia",
341e13c2760SPrzemyslaw Czarnowski                                         resName);
342e13c2760SPrzemyslaw Czarnowski 
343e13c2760SPrzemyslaw Czarnowski                                     return;
344e13c2760SPrzemyslaw Czarnowski                                 }
345e13c2760SPrzemyslaw Czarnowski 
346e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Legacy");
347e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
348e13c2760SPrzemyslaw Czarnowski                                 {
349e13c2760SPrzemyslaw Czarnowski                                     // Legacy mode
350e13c2760SPrzemyslaw Czarnowski                                     std::string imageUrl;
351e13c2760SPrzemyslaw Czarnowski 
352e13c2760SPrzemyslaw Czarnowski                                     // Read obligatory paramters (url of image)
353e13c2760SPrzemyslaw Czarnowski                                     if (!json_util::readJson(req, aResp->res,
354e13c2760SPrzemyslaw Czarnowski                                                              "Image", imageUrl))
355e13c2760SPrzemyslaw Czarnowski                                     {
356e13c2760SPrzemyslaw Czarnowski                                         BMCWEB_LOG_DEBUG
357e13c2760SPrzemyslaw Czarnowski                                             << "Image is not provided";
358e13c2760SPrzemyslaw Czarnowski                                         return;
359e13c2760SPrzemyslaw Czarnowski                                     }
360e13c2760SPrzemyslaw Czarnowski 
361e13c2760SPrzemyslaw Czarnowski                                     // must not be empty
362e13c2760SPrzemyslaw Czarnowski                                     if (imageUrl.size() == 0)
363e13c2760SPrzemyslaw Czarnowski                                     {
364e13c2760SPrzemyslaw Czarnowski                                         BMCWEB_LOG_ERROR
365e13c2760SPrzemyslaw Czarnowski                                             << "Request action parameter "
366e13c2760SPrzemyslaw Czarnowski                                                "Image is empty.";
367e13c2760SPrzemyslaw Czarnowski                                         messages::propertyValueFormatError(
368e13c2760SPrzemyslaw Czarnowski                                             aResp->res, "<empty>", "Image");
369e13c2760SPrzemyslaw Czarnowski 
370e13c2760SPrzemyslaw Czarnowski                                         return;
371e13c2760SPrzemyslaw Czarnowski                                     }
372e13c2760SPrzemyslaw Czarnowski 
373e13c2760SPrzemyslaw Czarnowski                                     // manager is irrelevant for VirtualMedia
374e13c2760SPrzemyslaw Czarnowski                                     // dbus calls
375e13c2760SPrzemyslaw Czarnowski                                     doVmAction(std::move(aResp), service,
376e13c2760SPrzemyslaw Czarnowski                                                resName, true, imageUrl);
377e13c2760SPrzemyslaw Czarnowski 
378e13c2760SPrzemyslaw Czarnowski                                     return;
379e13c2760SPrzemyslaw Czarnowski                                 }
380e13c2760SPrzemyslaw Czarnowski                             }
381e13c2760SPrzemyslaw Czarnowski                         }
382e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_DEBUG << "Parent item not found";
383e13c2760SPrzemyslaw Czarnowski                         messages::resourceNotFound(aResp->res, "VirtualMedia",
384e13c2760SPrzemyslaw Czarnowski                                                    resName);
385e13c2760SPrzemyslaw Czarnowski                     },
386e13c2760SPrzemyslaw Czarnowski                     service, "/xyz/openbmc_project/VirtualMedia",
387e13c2760SPrzemyslaw Czarnowski                     "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
388e13c2760SPrzemyslaw Czarnowski             },
389e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
390e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
391e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
392e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
393e13c2760SPrzemyslaw Czarnowski     }
394e13c2760SPrzemyslaw Czarnowski 
395e13c2760SPrzemyslaw Czarnowski     /**
396e13c2760SPrzemyslaw Czarnowski      * @brief Function transceives data with dbus directly.
397e13c2760SPrzemyslaw Czarnowski      *
398e13c2760SPrzemyslaw Czarnowski      * All BMC state properties will be retrieved before sending reset request.
399e13c2760SPrzemyslaw Czarnowski      */
400e13c2760SPrzemyslaw Czarnowski     void doVmAction(std::shared_ptr<AsyncResp> asyncResp,
401e13c2760SPrzemyslaw Czarnowski                     const std::string &service, const std::string &name,
402e13c2760SPrzemyslaw Czarnowski                     bool legacy, const std::string &imageUrl)
403e13c2760SPrzemyslaw Czarnowski     {
404e13c2760SPrzemyslaw Czarnowski 
405e13c2760SPrzemyslaw Czarnowski         // Legacy mount requires parameter with image
406e13c2760SPrzemyslaw Czarnowski         if (legacy)
407e13c2760SPrzemyslaw Czarnowski         {
408e13c2760SPrzemyslaw Czarnowski             crow::connections::systemBus->async_method_call(
409e13c2760SPrzemyslaw Czarnowski                 [asyncResp](const boost::system::error_code ec) {
410e13c2760SPrzemyslaw Czarnowski                     if (ec)
411e13c2760SPrzemyslaw Czarnowski                     {
412e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
413e13c2760SPrzemyslaw Czarnowski                         messages::internalError(asyncResp->res);
414e13c2760SPrzemyslaw Czarnowski 
415e13c2760SPrzemyslaw Czarnowski                         return;
416e13c2760SPrzemyslaw Czarnowski                     }
417e13c2760SPrzemyslaw Czarnowski                 },
418e13c2760SPrzemyslaw Czarnowski                 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
419e13c2760SPrzemyslaw Czarnowski                 "xyz.openbmc_project.VirtualMedia.Legacy", "Mount", imageUrl);
420e13c2760SPrzemyslaw Czarnowski         }
421e13c2760SPrzemyslaw Czarnowski         else // proxy
422e13c2760SPrzemyslaw Czarnowski         {
423e13c2760SPrzemyslaw Czarnowski             crow::connections::systemBus->async_method_call(
424e13c2760SPrzemyslaw Czarnowski                 [asyncResp](const boost::system::error_code ec) {
425e13c2760SPrzemyslaw Czarnowski                     if (ec)
426e13c2760SPrzemyslaw Czarnowski                     {
427e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
428e13c2760SPrzemyslaw Czarnowski                         messages::internalError(asyncResp->res);
429e13c2760SPrzemyslaw Czarnowski 
430e13c2760SPrzemyslaw Czarnowski                         return;
431e13c2760SPrzemyslaw Czarnowski                     }
432e13c2760SPrzemyslaw Czarnowski                 },
433e13c2760SPrzemyslaw Czarnowski                 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
434e13c2760SPrzemyslaw Czarnowski                 "xyz.openbmc_project.VirtualMedia.Proxy", "Mount");
435e13c2760SPrzemyslaw Czarnowski         }
436e13c2760SPrzemyslaw Czarnowski     }
437e13c2760SPrzemyslaw Czarnowski };
438e13c2760SPrzemyslaw Czarnowski 
439e13c2760SPrzemyslaw Czarnowski /**
440e13c2760SPrzemyslaw Czarnowski    @brief EjectMedia action class
441e13c2760SPrzemyslaw Czarnowski  */
442e13c2760SPrzemyslaw Czarnowski class VirtualMediaActionEjectMedia : public Node
443e13c2760SPrzemyslaw Czarnowski {
444e13c2760SPrzemyslaw Czarnowski   public:
445e13c2760SPrzemyslaw Czarnowski     VirtualMediaActionEjectMedia(CrowApp &app) :
446e13c2760SPrzemyslaw Czarnowski         Node(app,
447e13c2760SPrzemyslaw Czarnowski              "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
448e13c2760SPrzemyslaw Czarnowski              "VirtualMedia.EjectMedia",
449e13c2760SPrzemyslaw Czarnowski              std::string(), std::string())
450e13c2760SPrzemyslaw Czarnowski     {
451e13c2760SPrzemyslaw Czarnowski         entityPrivileges = {
452e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
453e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
454e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
455e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
456e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
457e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
458e13c2760SPrzemyslaw Czarnowski     }
459e13c2760SPrzemyslaw Czarnowski 
460e13c2760SPrzemyslaw Czarnowski   private:
461e13c2760SPrzemyslaw Czarnowski     /**
462e13c2760SPrzemyslaw Czarnowski      * @brief Function handles POST method request.
463e13c2760SPrzemyslaw Czarnowski      *
464e13c2760SPrzemyslaw Czarnowski      * Analyzes POST body message before sends Reset request data to dbus.
465e13c2760SPrzemyslaw Czarnowski      */
466e13c2760SPrzemyslaw Czarnowski     void doPost(crow::Response &res, const crow::Request &req,
467e13c2760SPrzemyslaw Czarnowski                 const std::vector<std::string> &params) override
468e13c2760SPrzemyslaw Czarnowski     {
469e13c2760SPrzemyslaw Czarnowski         auto aResp = std::make_shared<AsyncResp>(res);
470e13c2760SPrzemyslaw Czarnowski 
471e13c2760SPrzemyslaw Czarnowski         if (params.size() != 2)
472e13c2760SPrzemyslaw Czarnowski         {
473e13c2760SPrzemyslaw Czarnowski             messages::internalError(res);
474e13c2760SPrzemyslaw Czarnowski             return;
475e13c2760SPrzemyslaw Czarnowski         }
476e13c2760SPrzemyslaw Czarnowski 
477e13c2760SPrzemyslaw Czarnowski         // take resource name from URL
478e13c2760SPrzemyslaw Czarnowski         const std::string &resName = params[1];
479e13c2760SPrzemyslaw Czarnowski 
480e13c2760SPrzemyslaw Czarnowski         if (params[0] != "bmc")
481e13c2760SPrzemyslaw Czarnowski         {
482e13c2760SPrzemyslaw Czarnowski             messages::resourceNotFound(res, "VirtualMedia.Eject", resName);
483e13c2760SPrzemyslaw Czarnowski 
484e13c2760SPrzemyslaw Czarnowski             return;
485e13c2760SPrzemyslaw Czarnowski         }
486e13c2760SPrzemyslaw Czarnowski 
487e13c2760SPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
488e13c2760SPrzemyslaw Czarnowski             [this, aResp{std::move(aResp)}, req,
489e13c2760SPrzemyslaw Czarnowski              resName](const boost::system::error_code ec,
490e13c2760SPrzemyslaw Czarnowski                       const GetObjectType &getObjectType) {
491e13c2760SPrzemyslaw Czarnowski                 if (ec)
492e13c2760SPrzemyslaw Czarnowski                 {
493e13c2760SPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
494e13c2760SPrzemyslaw Czarnowski                                      << ec;
495e13c2760SPrzemyslaw Czarnowski                     messages::internalError(aResp->res);
496e13c2760SPrzemyslaw Czarnowski 
497e13c2760SPrzemyslaw Czarnowski                     return;
498e13c2760SPrzemyslaw Czarnowski                 }
499e13c2760SPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
500e13c2760SPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
501e13c2760SPrzemyslaw Czarnowski 
502e13c2760SPrzemyslaw Czarnowski                 crow::connections::systemBus->async_method_call(
503e13c2760SPrzemyslaw Czarnowski                     [this, resName, service, req, aResp{std::move(aResp)}](
504e13c2760SPrzemyslaw Czarnowski                         const boost::system::error_code ec,
505e13c2760SPrzemyslaw Czarnowski                         ManagedObjectType &subtree) {
506e13c2760SPrzemyslaw Czarnowski                         if (ec)
507e13c2760SPrzemyslaw Czarnowski                         {
508e13c2760SPrzemyslaw Czarnowski                             BMCWEB_LOG_DEBUG << "DBUS response error";
509e13c2760SPrzemyslaw Czarnowski 
510e13c2760SPrzemyslaw Czarnowski                             return;
511e13c2760SPrzemyslaw Czarnowski                         }
512e13c2760SPrzemyslaw Czarnowski 
513e13c2760SPrzemyslaw Czarnowski                         for (const auto &object : subtree)
514e13c2760SPrzemyslaw Czarnowski                         {
515e13c2760SPrzemyslaw Czarnowski                             const std::string &path =
516e13c2760SPrzemyslaw Czarnowski                                 static_cast<const std::string &>(object.first);
517e13c2760SPrzemyslaw Czarnowski 
518e13c2760SPrzemyslaw Czarnowski                             std::size_t lastIndex = path.rfind("/");
519e13c2760SPrzemyslaw Czarnowski                             if (lastIndex == std::string::npos)
520e13c2760SPrzemyslaw Czarnowski                             {
521e13c2760SPrzemyslaw Czarnowski                                 continue;
522e13c2760SPrzemyslaw Czarnowski                             }
523e13c2760SPrzemyslaw Czarnowski 
524e13c2760SPrzemyslaw Czarnowski                             lastIndex += 1;
525e13c2760SPrzemyslaw Czarnowski 
526e13c2760SPrzemyslaw Czarnowski                             if (path.substr(lastIndex) == resName)
527e13c2760SPrzemyslaw Czarnowski                             {
528e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Proxy");
529e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
530e13c2760SPrzemyslaw Czarnowski                                 {
531e13c2760SPrzemyslaw Czarnowski                                     // Proxy mode
532e13c2760SPrzemyslaw Czarnowski                                     doVmAction(std::move(aResp), service,
533e13c2760SPrzemyslaw Czarnowski                                                resName, false);
534e13c2760SPrzemyslaw Czarnowski                                 }
535e13c2760SPrzemyslaw Czarnowski 
536e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Legacy");
537e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
538e13c2760SPrzemyslaw Czarnowski                                 {
539e13c2760SPrzemyslaw Czarnowski                                     // Legacy mode
540e13c2760SPrzemyslaw Czarnowski                                     doVmAction(std::move(aResp), service,
541e13c2760SPrzemyslaw Czarnowski                                                resName, true);
542e13c2760SPrzemyslaw Czarnowski                                 }
543e13c2760SPrzemyslaw Czarnowski 
544e13c2760SPrzemyslaw Czarnowski                                 return;
545e13c2760SPrzemyslaw Czarnowski                             }
546e13c2760SPrzemyslaw Czarnowski                         }
547e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_DEBUG << "Parent item not found";
548e13c2760SPrzemyslaw Czarnowski                         messages::resourceNotFound(aResp->res, "VirtualMedia",
549e13c2760SPrzemyslaw Czarnowski                                                    resName);
550e13c2760SPrzemyslaw Czarnowski                     },
551e13c2760SPrzemyslaw Czarnowski                     service, "/xyz/openbmc_project/VirtualMedia",
552e13c2760SPrzemyslaw Czarnowski                     "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
553e13c2760SPrzemyslaw Czarnowski             },
554e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
555e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
556e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
557e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
558e13c2760SPrzemyslaw Czarnowski     }
559e13c2760SPrzemyslaw Czarnowski 
560e13c2760SPrzemyslaw Czarnowski     /**
561e13c2760SPrzemyslaw Czarnowski      * @brief Function transceives data with dbus directly.
562e13c2760SPrzemyslaw Czarnowski      *
563e13c2760SPrzemyslaw Czarnowski      * All BMC state properties will be retrieved before sending reset request.
564e13c2760SPrzemyslaw Czarnowski      */
565e13c2760SPrzemyslaw Czarnowski     void doVmAction(std::shared_ptr<AsyncResp> asyncResp,
566e13c2760SPrzemyslaw Czarnowski                     const std::string &service, const std::string &name,
567e13c2760SPrzemyslaw Czarnowski                     bool legacy)
568e13c2760SPrzemyslaw Czarnowski     {
569e13c2760SPrzemyslaw Czarnowski 
570e13c2760SPrzemyslaw Czarnowski         // Legacy mount requires parameter with image
571e13c2760SPrzemyslaw Czarnowski         if (legacy)
572e13c2760SPrzemyslaw Czarnowski         {
573e13c2760SPrzemyslaw Czarnowski             crow::connections::systemBus->async_method_call(
574e13c2760SPrzemyslaw Czarnowski                 [asyncResp](const boost::system::error_code ec) {
575e13c2760SPrzemyslaw Czarnowski                     if (ec)
576e13c2760SPrzemyslaw Czarnowski                     {
577e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
578e13c2760SPrzemyslaw Czarnowski 
579e13c2760SPrzemyslaw Czarnowski                         messages::internalError(asyncResp->res);
580e13c2760SPrzemyslaw Czarnowski                         return;
581e13c2760SPrzemyslaw Czarnowski                     }
582e13c2760SPrzemyslaw Czarnowski                 },
583e13c2760SPrzemyslaw Czarnowski                 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
584e13c2760SPrzemyslaw Czarnowski                 "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
585e13c2760SPrzemyslaw Czarnowski         }
586e13c2760SPrzemyslaw Czarnowski         else // proxy
587e13c2760SPrzemyslaw Czarnowski         {
588e13c2760SPrzemyslaw Czarnowski             crow::connections::systemBus->async_method_call(
589e13c2760SPrzemyslaw Czarnowski                 [asyncResp](const boost::system::error_code ec) {
590e13c2760SPrzemyslaw Czarnowski                     if (ec)
591e13c2760SPrzemyslaw Czarnowski                     {
592e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
593e13c2760SPrzemyslaw Czarnowski 
594e13c2760SPrzemyslaw Czarnowski                         messages::internalError(asyncResp->res);
595e13c2760SPrzemyslaw Czarnowski                         return;
596e13c2760SPrzemyslaw Czarnowski                     }
597e13c2760SPrzemyslaw Czarnowski                 },
598e13c2760SPrzemyslaw Czarnowski                 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
599e13c2760SPrzemyslaw Czarnowski                 "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
600e13c2760SPrzemyslaw Czarnowski         }
601e13c2760SPrzemyslaw Czarnowski     }
602e13c2760SPrzemyslaw Czarnowski };
603e13c2760SPrzemyslaw Czarnowski 
604107077deSPrzemyslaw Czarnowski class VirtualMediaCollection : public Node
605107077deSPrzemyslaw Czarnowski {
606107077deSPrzemyslaw Czarnowski   public:
607107077deSPrzemyslaw Czarnowski     /*
608107077deSPrzemyslaw Czarnowski      * Default Constructor
609107077deSPrzemyslaw Czarnowski      */
610107077deSPrzemyslaw Czarnowski     VirtualMediaCollection(CrowApp &app) :
611107077deSPrzemyslaw Czarnowski         Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/", std::string())
612107077deSPrzemyslaw Czarnowski     {
613107077deSPrzemyslaw Czarnowski         entityPrivileges = {
614107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
615107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
616107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
617107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
618107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
619107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
620107077deSPrzemyslaw Czarnowski     }
621107077deSPrzemyslaw Czarnowski 
622107077deSPrzemyslaw Czarnowski   private:
623107077deSPrzemyslaw Czarnowski     /**
624107077deSPrzemyslaw Czarnowski      * Functions triggers appropriate requests on DBus
625107077deSPrzemyslaw Czarnowski      */
626107077deSPrzemyslaw Czarnowski     void doGet(crow::Response &res, const crow::Request &req,
627107077deSPrzemyslaw Czarnowski                const std::vector<std::string> &params) override
628107077deSPrzemyslaw Czarnowski     {
629107077deSPrzemyslaw Czarnowski         auto asyncResp = std::make_shared<AsyncResp>(res);
630107077deSPrzemyslaw Czarnowski 
631107077deSPrzemyslaw Czarnowski         // Check if there is required param, truly entering this shall be
632107077deSPrzemyslaw Czarnowski         // impossible
633107077deSPrzemyslaw Czarnowski         if (params.size() != 1)
634107077deSPrzemyslaw Czarnowski         {
635107077deSPrzemyslaw Czarnowski             messages::internalError(res);
636107077deSPrzemyslaw Czarnowski 
637107077deSPrzemyslaw Czarnowski             return;
638107077deSPrzemyslaw Czarnowski         }
639107077deSPrzemyslaw Czarnowski 
640107077deSPrzemyslaw Czarnowski         const std::string &name = params[0];
641107077deSPrzemyslaw Czarnowski 
642107077deSPrzemyslaw Czarnowski         if (name != "bmc")
643107077deSPrzemyslaw Czarnowski         {
644107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
645107077deSPrzemyslaw Czarnowski 
646107077deSPrzemyslaw Czarnowski             return;
647107077deSPrzemyslaw Czarnowski         }
648107077deSPrzemyslaw Czarnowski 
649107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.type"] =
650107077deSPrzemyslaw Czarnowski             "#VirtualMediaCollection.VirtualMediaCollection";
651107077deSPrzemyslaw Czarnowski         res.jsonValue["Name"] = "Virtual Media Services";
652107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.context"] =
653107077deSPrzemyslaw Czarnowski             "/redfish/v1/"
654107077deSPrzemyslaw Czarnowski             "$metadata#VirtualMediaCollection.VirtualMediaCollection";
655107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.id"] =
656107077deSPrzemyslaw Czarnowski             "/redfish/v1/Managers/" + name + "/VirtualMedia/";
657107077deSPrzemyslaw Czarnowski 
658107077deSPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
659107077deSPrzemyslaw Czarnowski             [asyncResp, name](const boost::system::error_code ec,
660107077deSPrzemyslaw Czarnowski                               const GetObjectType &getObjectType) {
661107077deSPrzemyslaw Czarnowski                 if (ec)
662107077deSPrzemyslaw Czarnowski                 {
663107077deSPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
664107077deSPrzemyslaw Czarnowski                                      << ec;
665107077deSPrzemyslaw Czarnowski                     messages::internalError(asyncResp->res);
666107077deSPrzemyslaw Czarnowski 
667107077deSPrzemyslaw Czarnowski                     return;
668107077deSPrzemyslaw Czarnowski                 }
669107077deSPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
670107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
671107077deSPrzemyslaw Czarnowski 
672107077deSPrzemyslaw Czarnowski                 getVmResourceList(asyncResp, service, name);
673107077deSPrzemyslaw Czarnowski             },
674107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
675107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
676107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
677107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
678107077deSPrzemyslaw Czarnowski     }
679107077deSPrzemyslaw Czarnowski };
680107077deSPrzemyslaw Czarnowski 
681107077deSPrzemyslaw Czarnowski class VirtualMedia : public Node
682107077deSPrzemyslaw Czarnowski {
683107077deSPrzemyslaw Czarnowski   public:
684107077deSPrzemyslaw Czarnowski     /*
685107077deSPrzemyslaw Czarnowski      * Default Constructor
686107077deSPrzemyslaw Czarnowski      */
687107077deSPrzemyslaw Czarnowski     VirtualMedia(CrowApp &app) :
688107077deSPrzemyslaw Czarnowski         Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/",
689107077deSPrzemyslaw Czarnowski              std::string(), std::string())
690107077deSPrzemyslaw Czarnowski     {
691107077deSPrzemyslaw Czarnowski         entityPrivileges = {
692107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
693107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
694107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
695107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
696107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
697107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
698107077deSPrzemyslaw Czarnowski     }
699107077deSPrzemyslaw Czarnowski 
700107077deSPrzemyslaw Czarnowski   private:
701107077deSPrzemyslaw Czarnowski     /**
702107077deSPrzemyslaw Czarnowski      * Functions triggers appropriate requests on DBus
703107077deSPrzemyslaw Czarnowski      */
704107077deSPrzemyslaw Czarnowski     void doGet(crow::Response &res, const crow::Request &req,
705107077deSPrzemyslaw Czarnowski                const std::vector<std::string> &params) override
706107077deSPrzemyslaw Czarnowski     {
707107077deSPrzemyslaw Czarnowski         // Check if there is required param, truly entering this shall be
708107077deSPrzemyslaw Czarnowski         // impossible
709107077deSPrzemyslaw Czarnowski         if (params.size() != 2)
710107077deSPrzemyslaw Czarnowski         {
711107077deSPrzemyslaw Czarnowski             messages::internalError(res);
712107077deSPrzemyslaw Czarnowski 
713107077deSPrzemyslaw Czarnowski             res.end();
714107077deSPrzemyslaw Czarnowski             return;
715107077deSPrzemyslaw Czarnowski         }
716107077deSPrzemyslaw Czarnowski         const std::string &name = params[0];
717107077deSPrzemyslaw Czarnowski         const std::string &resName = params[1];
718107077deSPrzemyslaw Czarnowski 
719107077deSPrzemyslaw Czarnowski         auto asyncResp = std::make_shared<AsyncResp>(res);
720107077deSPrzemyslaw Czarnowski 
721107077deSPrzemyslaw Czarnowski         if (name != "bmc")
722107077deSPrzemyslaw Czarnowski         {
723107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
724107077deSPrzemyslaw Czarnowski 
725107077deSPrzemyslaw Czarnowski             return;
726107077deSPrzemyslaw Czarnowski         }
727107077deSPrzemyslaw Czarnowski 
728107077deSPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
729107077deSPrzemyslaw Czarnowski             [asyncResp, name, resName](const boost::system::error_code ec,
730107077deSPrzemyslaw Czarnowski                                        const GetObjectType &getObjectType) {
731107077deSPrzemyslaw Czarnowski                 if (ec)
732107077deSPrzemyslaw Czarnowski                 {
733107077deSPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
734107077deSPrzemyslaw Czarnowski                                      << ec;
735107077deSPrzemyslaw Czarnowski                     messages::internalError(asyncResp->res);
736107077deSPrzemyslaw Czarnowski 
737107077deSPrzemyslaw Czarnowski                     return;
738107077deSPrzemyslaw Czarnowski                 }
739107077deSPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
740107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
741107077deSPrzemyslaw Czarnowski 
742107077deSPrzemyslaw Czarnowski                 getVmData(asyncResp, service, name, resName);
743107077deSPrzemyslaw Czarnowski             },
744107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
745107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
746107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
747107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
748107077deSPrzemyslaw Czarnowski     }
749107077deSPrzemyslaw Czarnowski };
750107077deSPrzemyslaw Czarnowski 
751107077deSPrzemyslaw Czarnowski } // namespace redfish
752