xref: /openbmc/bmcweb/features/redfish/lib/virtual_media.hpp (revision d6da5bebfe4c0ac206570cd69f20406da06ea40b)
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
78d04ba325SPrzemyslaw Czarnowski             aResp->res.jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
79d04ba325SPrzemyslaw 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;
119d04ba325SPrzemyslaw Czarnowski     item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
120107077deSPrzemyslaw Czarnowski     item["Name"] = "Virtual Removable Media";
121107077deSPrzemyslaw Czarnowski     item["Id"] = resName;
122107077deSPrzemyslaw Czarnowski     item["Image"] = nullptr;
123107077deSPrzemyslaw Czarnowski     item["Inserted"] = nullptr;
124107077deSPrzemyslaw Czarnowski     item["ImageName"] = nullptr;
125107077deSPrzemyslaw Czarnowski     item["WriteProtected"] = true;
126107077deSPrzemyslaw Czarnowski     item["ConnectedVia"] = "NotConnected";
127107077deSPrzemyslaw Czarnowski     item["MediaTypes"] = {"CD", "USBStick"};
128107077deSPrzemyslaw Czarnowski     item["TransferMethod"] = "Stream";
129107077deSPrzemyslaw Czarnowski     item["TransferProtocolType"] = nullptr;
130d04ba325SPrzemyslaw Czarnowski     item["Oem"]["OpenBmc"]["WebSocketEndpoint"] = nullptr;
131d04ba325SPrzemyslaw Czarnowski     item["Oem"]["OpenBMC"]["@odata.type"] =
132d04ba325SPrzemyslaw Czarnowski         "#OemVirtualMedia.v1_0_0.VirtualMedia";
133107077deSPrzemyslaw Czarnowski 
134107077deSPrzemyslaw Czarnowski     return item;
135107077deSPrzemyslaw Czarnowski }
136107077deSPrzemyslaw Czarnowski 
137107077deSPrzemyslaw Czarnowski /**
138107077deSPrzemyslaw Czarnowski  *  @brief Fills collection data
139107077deSPrzemyslaw Czarnowski  */
140107077deSPrzemyslaw Czarnowski static void getVmResourceList(std::shared_ptr<AsyncResp> aResp,
141107077deSPrzemyslaw Czarnowski                               const std::string &service,
142107077deSPrzemyslaw Czarnowski                               const std::string &name)
143107077deSPrzemyslaw Czarnowski {
144107077deSPrzemyslaw Czarnowski     BMCWEB_LOG_DEBUG << "Get available Virtual Media resources.";
145107077deSPrzemyslaw Czarnowski     crow::connections::systemBus->async_method_call(
146107077deSPrzemyslaw Czarnowski         [name, aResp{std::move(aResp)}](const boost::system::error_code ec,
147107077deSPrzemyslaw Czarnowski                                         ManagedObjectType &subtree) {
148107077deSPrzemyslaw Czarnowski             if (ec)
149107077deSPrzemyslaw Czarnowski             {
150107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "DBUS response error";
151107077deSPrzemyslaw Czarnowski                 return;
152107077deSPrzemyslaw Czarnowski             }
153107077deSPrzemyslaw Czarnowski             nlohmann::json &members = aResp->res.jsonValue["Members"];
154107077deSPrzemyslaw Czarnowski             members = nlohmann::json::array();
155107077deSPrzemyslaw Czarnowski 
156107077deSPrzemyslaw Czarnowski             for (const auto &object : subtree)
157107077deSPrzemyslaw Czarnowski             {
158107077deSPrzemyslaw Czarnowski                 nlohmann::json item;
159107077deSPrzemyslaw Czarnowski                 const std::string &path =
160107077deSPrzemyslaw Czarnowski                     static_cast<const std::string &>(object.first);
161107077deSPrzemyslaw Czarnowski                 std::size_t lastIndex = path.rfind("/");
162107077deSPrzemyslaw Czarnowski                 if (lastIndex == std::string::npos)
163107077deSPrzemyslaw Czarnowski                 {
164107077deSPrzemyslaw Czarnowski                     continue;
165107077deSPrzemyslaw Czarnowski                 }
166107077deSPrzemyslaw Czarnowski 
167107077deSPrzemyslaw Czarnowski                 lastIndex += 1;
168107077deSPrzemyslaw Czarnowski 
169107077deSPrzemyslaw Czarnowski                 item["@odata.id"] = "/redfish/v1/Managers/" + name +
170107077deSPrzemyslaw Czarnowski                                     "/VirtualMedia/" + path.substr(lastIndex);
171107077deSPrzemyslaw Czarnowski 
172107077deSPrzemyslaw Czarnowski                 members.emplace_back(std::move(item));
173107077deSPrzemyslaw Czarnowski             }
174107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["Members@odata.count"] = members.size();
175107077deSPrzemyslaw Czarnowski         },
176107077deSPrzemyslaw Czarnowski         service, "/xyz/openbmc_project/VirtualMedia",
177107077deSPrzemyslaw Czarnowski         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
178107077deSPrzemyslaw Czarnowski }
179107077deSPrzemyslaw Czarnowski 
180107077deSPrzemyslaw Czarnowski /**
181107077deSPrzemyslaw Czarnowski  *  @brief Fills data for specific resource
182107077deSPrzemyslaw Czarnowski  */
183107077deSPrzemyslaw Czarnowski static void getVmData(std::shared_ptr<AsyncResp> aResp,
184107077deSPrzemyslaw Czarnowski                       const std::string &service, const std::string &name,
185107077deSPrzemyslaw Czarnowski                       const std::string &resName)
186107077deSPrzemyslaw Czarnowski {
187107077deSPrzemyslaw Czarnowski     BMCWEB_LOG_DEBUG << "Get Virtual Media resource data.";
188107077deSPrzemyslaw Czarnowski 
189107077deSPrzemyslaw Czarnowski     crow::connections::systemBus->async_method_call(
190107077deSPrzemyslaw Czarnowski         [resName, name, aResp](const boost::system::error_code ec,
191107077deSPrzemyslaw Czarnowski                                ManagedObjectType &subtree) {
192107077deSPrzemyslaw Czarnowski             if (ec)
193107077deSPrzemyslaw Czarnowski             {
194107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "DBUS response error";
195e13c2760SPrzemyslaw Czarnowski 
196107077deSPrzemyslaw Czarnowski                 return;
197107077deSPrzemyslaw Czarnowski             }
198107077deSPrzemyslaw Czarnowski 
199107077deSPrzemyslaw Czarnowski             for (auto &item : subtree)
200107077deSPrzemyslaw Czarnowski             {
201107077deSPrzemyslaw Czarnowski                 const std::string &path =
202107077deSPrzemyslaw Czarnowski                     static_cast<const std::string &>(item.first);
203107077deSPrzemyslaw Czarnowski 
204107077deSPrzemyslaw Czarnowski                 std::size_t lastItem = path.rfind("/");
205107077deSPrzemyslaw Czarnowski                 if (lastItem == std::string::npos)
206107077deSPrzemyslaw Czarnowski                 {
207107077deSPrzemyslaw Czarnowski                     continue;
208107077deSPrzemyslaw Czarnowski                 }
209107077deSPrzemyslaw Czarnowski 
210107077deSPrzemyslaw Czarnowski                 if (path.substr(lastItem + 1) != resName)
211107077deSPrzemyslaw Czarnowski                 {
212107077deSPrzemyslaw Czarnowski                     continue;
213107077deSPrzemyslaw Czarnowski                 }
214107077deSPrzemyslaw Czarnowski 
215107077deSPrzemyslaw Czarnowski                 aResp->res.jsonValue = vmItemTemplate(name, resName);
216107077deSPrzemyslaw Czarnowski 
217e13c2760SPrzemyslaw Czarnowski                 // Check if dbus path is Legacy type
218e13c2760SPrzemyslaw Czarnowski                 if (path.find("VirtualMedia/Legacy") != std::string::npos)
219e13c2760SPrzemyslaw Czarnowski                 {
220e13c2760SPrzemyslaw Czarnowski                     aResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
221e13c2760SPrzemyslaw Czarnowski                                         ["target"] =
222e13c2760SPrzemyslaw Czarnowski                         "/redfish/v1/Managers/" + name + "/VirtualMedia/" +
223e13c2760SPrzemyslaw Czarnowski                         resName + "/Actions/VirtualMedia.InsertMedia";
224e13c2760SPrzemyslaw Czarnowski                 }
225e13c2760SPrzemyslaw Czarnowski 
226107077deSPrzemyslaw Czarnowski                 vmParseInterfaceObject(item.second, aResp);
227107077deSPrzemyslaw Czarnowski 
228e13c2760SPrzemyslaw Czarnowski                 aResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
229e13c2760SPrzemyslaw Czarnowski                                     ["target"] =
230e13c2760SPrzemyslaw Czarnowski                     "/redfish/v1/Managers/" + name + "/VirtualMedia/" +
231e13c2760SPrzemyslaw Czarnowski                     resName + "/Actions/VirtualMedia.EjectMedia";
232e13c2760SPrzemyslaw Czarnowski 
233107077deSPrzemyslaw Czarnowski                 return;
234107077deSPrzemyslaw Czarnowski             }
235107077deSPrzemyslaw Czarnowski 
236107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(
237d04ba325SPrzemyslaw Czarnowski                 aResp->res, "#VirtualMedia.v1_3_0.VirtualMedia", resName);
238107077deSPrzemyslaw Czarnowski         },
239107077deSPrzemyslaw Czarnowski         service, "/xyz/openbmc_project/VirtualMedia",
240107077deSPrzemyslaw Czarnowski         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
241107077deSPrzemyslaw Czarnowski }
242107077deSPrzemyslaw Czarnowski 
243e13c2760SPrzemyslaw Czarnowski /**
244e13c2760SPrzemyslaw Czarnowski    @brief InsertMedia action class
245e13c2760SPrzemyslaw Czarnowski  */
246e13c2760SPrzemyslaw Czarnowski class VirtualMediaActionInsertMedia : public Node
247e13c2760SPrzemyslaw Czarnowski {
248e13c2760SPrzemyslaw Czarnowski   public:
249e13c2760SPrzemyslaw Czarnowski     VirtualMediaActionInsertMedia(CrowApp &app) :
250e13c2760SPrzemyslaw Czarnowski         Node(app,
251e13c2760SPrzemyslaw Czarnowski              "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
252e13c2760SPrzemyslaw Czarnowski              "VirtualMedia.InsertMedia",
253e13c2760SPrzemyslaw Czarnowski              std::string(), std::string())
254e13c2760SPrzemyslaw Czarnowski     {
255e13c2760SPrzemyslaw Czarnowski         entityPrivileges = {
256e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
257e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
258e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
259e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
260e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
261e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
262e13c2760SPrzemyslaw Czarnowski     }
263e13c2760SPrzemyslaw Czarnowski 
264e13c2760SPrzemyslaw Czarnowski   private:
265e13c2760SPrzemyslaw Czarnowski     /**
266e13c2760SPrzemyslaw Czarnowski      * @brief Function handles POST method request.
267e13c2760SPrzemyslaw Czarnowski      *
268e13c2760SPrzemyslaw Czarnowski      * Analyzes POST body message before sends Reset request data to dbus.
269e13c2760SPrzemyslaw Czarnowski      */
270e13c2760SPrzemyslaw Czarnowski     void doPost(crow::Response &res, const crow::Request &req,
271e13c2760SPrzemyslaw Czarnowski                 const std::vector<std::string> &params) override
272e13c2760SPrzemyslaw Czarnowski     {
273e13c2760SPrzemyslaw Czarnowski         auto aResp = std::make_shared<AsyncResp>(res);
274e13c2760SPrzemyslaw Czarnowski 
275e13c2760SPrzemyslaw Czarnowski         if (params.size() != 2)
276e13c2760SPrzemyslaw Czarnowski         {
277e13c2760SPrzemyslaw Czarnowski             messages::internalError(res);
278e13c2760SPrzemyslaw Czarnowski             return;
279e13c2760SPrzemyslaw Czarnowski         }
280e13c2760SPrzemyslaw Czarnowski 
281e13c2760SPrzemyslaw Czarnowski         // take resource name from URL
282e13c2760SPrzemyslaw Czarnowski         const std::string &resName = params[1];
283e13c2760SPrzemyslaw Czarnowski 
284e13c2760SPrzemyslaw Czarnowski         if (params[0] != "bmc")
285e13c2760SPrzemyslaw Czarnowski         {
286e13c2760SPrzemyslaw Czarnowski             messages::resourceNotFound(res, "VirtualMedia.Insert", resName);
287e13c2760SPrzemyslaw Czarnowski 
288e13c2760SPrzemyslaw Czarnowski             return;
289e13c2760SPrzemyslaw Czarnowski         }
290e13c2760SPrzemyslaw Czarnowski 
291e13c2760SPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
292e13c2760SPrzemyslaw Czarnowski             [this, aResp{std::move(aResp)}, req,
293e13c2760SPrzemyslaw Czarnowski              resName](const boost::system::error_code ec,
294e13c2760SPrzemyslaw Czarnowski                       const GetObjectType &getObjectType) {
295e13c2760SPrzemyslaw Czarnowski                 if (ec)
296e13c2760SPrzemyslaw Czarnowski                 {
297e13c2760SPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
298e13c2760SPrzemyslaw Czarnowski                                      << ec;
299e13c2760SPrzemyslaw Czarnowski                     messages::internalError(aResp->res);
300e13c2760SPrzemyslaw Czarnowski 
301e13c2760SPrzemyslaw Czarnowski                     return;
302e13c2760SPrzemyslaw Czarnowski                 }
303e13c2760SPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
304e13c2760SPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
305e13c2760SPrzemyslaw Czarnowski 
306e13c2760SPrzemyslaw Czarnowski                 crow::connections::systemBus->async_method_call(
307e13c2760SPrzemyslaw Czarnowski                     [this, service, resName, req, aResp{std::move(aResp)}](
308e13c2760SPrzemyslaw Czarnowski                         const boost::system::error_code ec,
309e13c2760SPrzemyslaw Czarnowski                         ManagedObjectType &subtree) {
310e13c2760SPrzemyslaw Czarnowski                         if (ec)
311e13c2760SPrzemyslaw Czarnowski                         {
312e13c2760SPrzemyslaw Czarnowski                             BMCWEB_LOG_DEBUG << "DBUS response error";
313e13c2760SPrzemyslaw Czarnowski 
314e13c2760SPrzemyslaw Czarnowski                             return;
315e13c2760SPrzemyslaw Czarnowski                         }
316e13c2760SPrzemyslaw Czarnowski 
317e13c2760SPrzemyslaw Czarnowski                         for (const auto &object : subtree)
318e13c2760SPrzemyslaw Czarnowski                         {
319e13c2760SPrzemyslaw Czarnowski                             const std::string &path =
320e13c2760SPrzemyslaw Czarnowski                                 static_cast<const std::string &>(object.first);
321e13c2760SPrzemyslaw Czarnowski 
322e13c2760SPrzemyslaw Czarnowski                             std::size_t lastIndex = path.rfind("/");
323e13c2760SPrzemyslaw Czarnowski                             if (lastIndex == std::string::npos)
324e13c2760SPrzemyslaw Czarnowski                             {
325e13c2760SPrzemyslaw Czarnowski                                 continue;
326e13c2760SPrzemyslaw Czarnowski                             }
327e13c2760SPrzemyslaw Czarnowski 
328e13c2760SPrzemyslaw Czarnowski                             lastIndex += 1;
329e13c2760SPrzemyslaw Czarnowski 
330e13c2760SPrzemyslaw Czarnowski                             if (path.substr(lastIndex) == resName)
331e13c2760SPrzemyslaw Czarnowski                             {
332e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Proxy");
333e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
334e13c2760SPrzemyslaw Czarnowski                                 {
335e13c2760SPrzemyslaw Czarnowski                                     // Not possible in proxy mode
336e13c2760SPrzemyslaw Czarnowski                                     BMCWEB_LOG_DEBUG << "InsertMedia not "
337e13c2760SPrzemyslaw Czarnowski                                                         "allowed in proxy mode";
338e13c2760SPrzemyslaw Czarnowski                                     messages::resourceNotFound(
339e13c2760SPrzemyslaw Czarnowski                                         aResp->res, "VirtualMedia.InsertMedia",
340e13c2760SPrzemyslaw Czarnowski                                         resName);
341e13c2760SPrzemyslaw Czarnowski 
342e13c2760SPrzemyslaw Czarnowski                                     return;
343e13c2760SPrzemyslaw Czarnowski                                 }
344e13c2760SPrzemyslaw Czarnowski 
345e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Legacy");
346e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
347e13c2760SPrzemyslaw Czarnowski                                 {
348e13c2760SPrzemyslaw Czarnowski                                     // Legacy mode
349e13c2760SPrzemyslaw Czarnowski                                     std::string imageUrl;
350*d6da5bebSAdrian Ambrożewicz                                     bool writeProtected;
351e13c2760SPrzemyslaw Czarnowski 
352e13c2760SPrzemyslaw Czarnowski                                     // Read obligatory paramters (url of image)
353*d6da5bebSAdrian Ambrożewicz                                     if (!json_util::readJson(
354*d6da5bebSAdrian Ambrożewicz                                             req, aResp->res, "Image", imageUrl,
355*d6da5bebSAdrian Ambrożewicz                                             "WriteProtected", writeProtected))
356*d6da5bebSAdrian Ambrożewicz 
357e13c2760SPrzemyslaw Czarnowski                                     {
358e13c2760SPrzemyslaw Czarnowski                                         BMCWEB_LOG_DEBUG
359e13c2760SPrzemyslaw Czarnowski                                             << "Image is not provided";
360e13c2760SPrzemyslaw Czarnowski                                         return;
361e13c2760SPrzemyslaw Czarnowski                                     }
362e13c2760SPrzemyslaw Czarnowski 
363e13c2760SPrzemyslaw Czarnowski                                     // must not be empty
364e13c2760SPrzemyslaw Czarnowski                                     if (imageUrl.size() == 0)
365e13c2760SPrzemyslaw Czarnowski                                     {
366e13c2760SPrzemyslaw Czarnowski                                         BMCWEB_LOG_ERROR
367e13c2760SPrzemyslaw Czarnowski                                             << "Request action parameter "
368e13c2760SPrzemyslaw Czarnowski                                                "Image is empty.";
369e13c2760SPrzemyslaw Czarnowski                                         messages::propertyValueFormatError(
370e13c2760SPrzemyslaw Czarnowski                                             aResp->res, "<empty>", "Image");
371e13c2760SPrzemyslaw Czarnowski 
372e13c2760SPrzemyslaw Czarnowski                                         return;
373e13c2760SPrzemyslaw Czarnowski                                     }
374e13c2760SPrzemyslaw Czarnowski 
375e13c2760SPrzemyslaw Czarnowski                                     // manager is irrelevant for VirtualMedia
376e13c2760SPrzemyslaw Czarnowski                                     // dbus calls
377*d6da5bebSAdrian Ambrożewicz                                     doMountVmLegacy(std::move(aResp), service,
378*d6da5bebSAdrian Ambrożewicz                                                     resName, imageUrl,
379*d6da5bebSAdrian Ambrożewicz                                                     !writeProtected);
380e13c2760SPrzemyslaw Czarnowski 
381e13c2760SPrzemyslaw Czarnowski                                     return;
382e13c2760SPrzemyslaw Czarnowski                                 }
383e13c2760SPrzemyslaw Czarnowski                             }
384e13c2760SPrzemyslaw Czarnowski                         }
385e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_DEBUG << "Parent item not found";
386e13c2760SPrzemyslaw Czarnowski                         messages::resourceNotFound(aResp->res, "VirtualMedia",
387e13c2760SPrzemyslaw Czarnowski                                                    resName);
388e13c2760SPrzemyslaw Czarnowski                     },
389e13c2760SPrzemyslaw Czarnowski                     service, "/xyz/openbmc_project/VirtualMedia",
390e13c2760SPrzemyslaw Czarnowski                     "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
391e13c2760SPrzemyslaw Czarnowski             },
392e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
393e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
394e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
395e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
396e13c2760SPrzemyslaw Czarnowski     }
397e13c2760SPrzemyslaw Czarnowski 
398e13c2760SPrzemyslaw Czarnowski     /**
399e13c2760SPrzemyslaw Czarnowski      * @brief Function transceives data with dbus directly.
400e13c2760SPrzemyslaw Czarnowski      *
401e13c2760SPrzemyslaw Czarnowski      * All BMC state properties will be retrieved before sending reset request.
402e13c2760SPrzemyslaw Czarnowski      */
403*d6da5bebSAdrian Ambrożewicz     void doMountVmLegacy(std::shared_ptr<AsyncResp> asyncResp,
404e13c2760SPrzemyslaw Czarnowski                          const std::string &service, const std::string &name,
405*d6da5bebSAdrian Ambrożewicz                          const std::string &imageUrl, const bool rw)
406e13c2760SPrzemyslaw Czarnowski     {
407e13c2760SPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
408*d6da5bebSAdrian Ambrożewicz             [asyncResp](const boost::system::error_code ec, bool success) {
409e13c2760SPrzemyslaw Czarnowski                 if (ec)
410e13c2760SPrzemyslaw Czarnowski                 {
411e13c2760SPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
412e13c2760SPrzemyslaw Czarnowski                     messages::internalError(asyncResp->res);
413*d6da5bebSAdrian Ambrożewicz                 }
414*d6da5bebSAdrian Ambrożewicz                 else if (!success)
415*d6da5bebSAdrian Ambrożewicz                 {
416*d6da5bebSAdrian Ambrożewicz                     BMCWEB_LOG_ERROR << "Service responded with error";
417*d6da5bebSAdrian Ambrożewicz                     messages::generalError(asyncResp->res);
418e13c2760SPrzemyslaw Czarnowski                 }
419e13c2760SPrzemyslaw Czarnowski             },
420e13c2760SPrzemyslaw Czarnowski             service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
421*d6da5bebSAdrian Ambrożewicz             "xyz.openbmc_project.VirtualMedia.Legacy", "Mount", imageUrl, rw);
422e13c2760SPrzemyslaw Czarnowski     }
423e13c2760SPrzemyslaw Czarnowski };
424e13c2760SPrzemyslaw Czarnowski 
425e13c2760SPrzemyslaw Czarnowski /**
426e13c2760SPrzemyslaw Czarnowski    @brief EjectMedia action class
427e13c2760SPrzemyslaw Czarnowski  */
428e13c2760SPrzemyslaw Czarnowski class VirtualMediaActionEjectMedia : public Node
429e13c2760SPrzemyslaw Czarnowski {
430e13c2760SPrzemyslaw Czarnowski   public:
431e13c2760SPrzemyslaw Czarnowski     VirtualMediaActionEjectMedia(CrowApp &app) :
432e13c2760SPrzemyslaw Czarnowski         Node(app,
433e13c2760SPrzemyslaw Czarnowski              "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
434e13c2760SPrzemyslaw Czarnowski              "VirtualMedia.EjectMedia",
435e13c2760SPrzemyslaw Czarnowski              std::string(), std::string())
436e13c2760SPrzemyslaw Czarnowski     {
437e13c2760SPrzemyslaw Czarnowski         entityPrivileges = {
438e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
439e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
440e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
441e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
442e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
443e13c2760SPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
444e13c2760SPrzemyslaw Czarnowski     }
445e13c2760SPrzemyslaw Czarnowski 
446e13c2760SPrzemyslaw Czarnowski   private:
447e13c2760SPrzemyslaw Czarnowski     /**
448e13c2760SPrzemyslaw Czarnowski      * @brief Function handles POST method request.
449e13c2760SPrzemyslaw Czarnowski      *
450e13c2760SPrzemyslaw Czarnowski      * Analyzes POST body message before sends Reset request data to dbus.
451e13c2760SPrzemyslaw Czarnowski      */
452e13c2760SPrzemyslaw Czarnowski     void doPost(crow::Response &res, const crow::Request &req,
453e13c2760SPrzemyslaw Czarnowski                 const std::vector<std::string> &params) override
454e13c2760SPrzemyslaw Czarnowski     {
455e13c2760SPrzemyslaw Czarnowski         auto aResp = std::make_shared<AsyncResp>(res);
456e13c2760SPrzemyslaw Czarnowski 
457e13c2760SPrzemyslaw Czarnowski         if (params.size() != 2)
458e13c2760SPrzemyslaw Czarnowski         {
459e13c2760SPrzemyslaw Czarnowski             messages::internalError(res);
460e13c2760SPrzemyslaw Czarnowski             return;
461e13c2760SPrzemyslaw Czarnowski         }
462e13c2760SPrzemyslaw Czarnowski 
463e13c2760SPrzemyslaw Czarnowski         // take resource name from URL
464e13c2760SPrzemyslaw Czarnowski         const std::string &resName = params[1];
465e13c2760SPrzemyslaw Czarnowski 
466e13c2760SPrzemyslaw Czarnowski         if (params[0] != "bmc")
467e13c2760SPrzemyslaw Czarnowski         {
468e13c2760SPrzemyslaw Czarnowski             messages::resourceNotFound(res, "VirtualMedia.Eject", resName);
469e13c2760SPrzemyslaw Czarnowski 
470e13c2760SPrzemyslaw Czarnowski             return;
471e13c2760SPrzemyslaw Czarnowski         }
472e13c2760SPrzemyslaw Czarnowski 
473e13c2760SPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
474e13c2760SPrzemyslaw Czarnowski             [this, aResp{std::move(aResp)}, req,
475e13c2760SPrzemyslaw Czarnowski              resName](const boost::system::error_code ec,
476e13c2760SPrzemyslaw Czarnowski                       const GetObjectType &getObjectType) {
477e13c2760SPrzemyslaw Czarnowski                 if (ec)
478e13c2760SPrzemyslaw Czarnowski                 {
479e13c2760SPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
480e13c2760SPrzemyslaw Czarnowski                                      << ec;
481e13c2760SPrzemyslaw Czarnowski                     messages::internalError(aResp->res);
482e13c2760SPrzemyslaw Czarnowski 
483e13c2760SPrzemyslaw Czarnowski                     return;
484e13c2760SPrzemyslaw Czarnowski                 }
485e13c2760SPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
486e13c2760SPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
487e13c2760SPrzemyslaw Czarnowski 
488e13c2760SPrzemyslaw Czarnowski                 crow::connections::systemBus->async_method_call(
489e13c2760SPrzemyslaw Czarnowski                     [this, resName, service, req, aResp{std::move(aResp)}](
490e13c2760SPrzemyslaw Czarnowski                         const boost::system::error_code ec,
491e13c2760SPrzemyslaw Czarnowski                         ManagedObjectType &subtree) {
492e13c2760SPrzemyslaw Czarnowski                         if (ec)
493e13c2760SPrzemyslaw Czarnowski                         {
494e13c2760SPrzemyslaw Czarnowski                             BMCWEB_LOG_DEBUG << "DBUS response error";
495e13c2760SPrzemyslaw Czarnowski 
496e13c2760SPrzemyslaw Czarnowski                             return;
497e13c2760SPrzemyslaw Czarnowski                         }
498e13c2760SPrzemyslaw Czarnowski 
499e13c2760SPrzemyslaw Czarnowski                         for (const auto &object : subtree)
500e13c2760SPrzemyslaw Czarnowski                         {
501e13c2760SPrzemyslaw Czarnowski                             const std::string &path =
502e13c2760SPrzemyslaw Czarnowski                                 static_cast<const std::string &>(object.first);
503e13c2760SPrzemyslaw Czarnowski 
504e13c2760SPrzemyslaw Czarnowski                             std::size_t lastIndex = path.rfind("/");
505e13c2760SPrzemyslaw Czarnowski                             if (lastIndex == std::string::npos)
506e13c2760SPrzemyslaw Czarnowski                             {
507e13c2760SPrzemyslaw Czarnowski                                 continue;
508e13c2760SPrzemyslaw Czarnowski                             }
509e13c2760SPrzemyslaw Czarnowski 
510e13c2760SPrzemyslaw Czarnowski                             lastIndex += 1;
511e13c2760SPrzemyslaw Czarnowski 
512e13c2760SPrzemyslaw Czarnowski                             if (path.substr(lastIndex) == resName)
513e13c2760SPrzemyslaw Czarnowski                             {
514e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Proxy");
515e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
516e13c2760SPrzemyslaw Czarnowski                                 {
517e13c2760SPrzemyslaw Czarnowski                                     // Proxy mode
518e13c2760SPrzemyslaw Czarnowski                                     doVmAction(std::move(aResp), service,
519e13c2760SPrzemyslaw Czarnowski                                                resName, false);
520e13c2760SPrzemyslaw Czarnowski                                 }
521e13c2760SPrzemyslaw Czarnowski 
522e13c2760SPrzemyslaw Czarnowski                                 lastIndex = path.rfind("Legacy");
523e13c2760SPrzemyslaw Czarnowski                                 if (lastIndex != std::string::npos)
524e13c2760SPrzemyslaw Czarnowski                                 {
525e13c2760SPrzemyslaw Czarnowski                                     // Legacy mode
526e13c2760SPrzemyslaw Czarnowski                                     doVmAction(std::move(aResp), service,
527e13c2760SPrzemyslaw Czarnowski                                                resName, true);
528e13c2760SPrzemyslaw Czarnowski                                 }
529e13c2760SPrzemyslaw Czarnowski 
530e13c2760SPrzemyslaw Czarnowski                                 return;
531e13c2760SPrzemyslaw Czarnowski                             }
532e13c2760SPrzemyslaw Czarnowski                         }
533e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_DEBUG << "Parent item not found";
534e13c2760SPrzemyslaw Czarnowski                         messages::resourceNotFound(aResp->res, "VirtualMedia",
535e13c2760SPrzemyslaw Czarnowski                                                    resName);
536e13c2760SPrzemyslaw Czarnowski                     },
537e13c2760SPrzemyslaw Czarnowski                     service, "/xyz/openbmc_project/VirtualMedia",
538e13c2760SPrzemyslaw Czarnowski                     "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
539e13c2760SPrzemyslaw Czarnowski             },
540e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
541e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
542e13c2760SPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
543e13c2760SPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
544e13c2760SPrzemyslaw Czarnowski     }
545e13c2760SPrzemyslaw Czarnowski 
546e13c2760SPrzemyslaw Czarnowski     /**
547e13c2760SPrzemyslaw Czarnowski      * @brief Function transceives data with dbus directly.
548e13c2760SPrzemyslaw Czarnowski      *
549e13c2760SPrzemyslaw Czarnowski      * All BMC state properties will be retrieved before sending reset request.
550e13c2760SPrzemyslaw Czarnowski      */
551e13c2760SPrzemyslaw Czarnowski     void doVmAction(std::shared_ptr<AsyncResp> asyncResp,
552e13c2760SPrzemyslaw Czarnowski                     const std::string &service, const std::string &name,
553e13c2760SPrzemyslaw Czarnowski                     bool legacy)
554e13c2760SPrzemyslaw Czarnowski     {
555e13c2760SPrzemyslaw Czarnowski 
556e13c2760SPrzemyslaw Czarnowski         // Legacy mount requires parameter with image
557e13c2760SPrzemyslaw Czarnowski         if (legacy)
558e13c2760SPrzemyslaw Czarnowski         {
559e13c2760SPrzemyslaw Czarnowski             crow::connections::systemBus->async_method_call(
560e13c2760SPrzemyslaw Czarnowski                 [asyncResp](const boost::system::error_code ec) {
561e13c2760SPrzemyslaw Czarnowski                     if (ec)
562e13c2760SPrzemyslaw Czarnowski                     {
563e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
564e13c2760SPrzemyslaw Czarnowski 
565e13c2760SPrzemyslaw Czarnowski                         messages::internalError(asyncResp->res);
566e13c2760SPrzemyslaw Czarnowski                         return;
567e13c2760SPrzemyslaw Czarnowski                     }
568e13c2760SPrzemyslaw Czarnowski                 },
569e13c2760SPrzemyslaw Czarnowski                 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
570e13c2760SPrzemyslaw Czarnowski                 "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
571e13c2760SPrzemyslaw Czarnowski         }
572e13c2760SPrzemyslaw Czarnowski         else // proxy
573e13c2760SPrzemyslaw Czarnowski         {
574e13c2760SPrzemyslaw Czarnowski             crow::connections::systemBus->async_method_call(
575e13c2760SPrzemyslaw Czarnowski                 [asyncResp](const boost::system::error_code ec) {
576e13c2760SPrzemyslaw Czarnowski                     if (ec)
577e13c2760SPrzemyslaw Czarnowski                     {
578e13c2760SPrzemyslaw Czarnowski                         BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
579e13c2760SPrzemyslaw Czarnowski 
580e13c2760SPrzemyslaw Czarnowski                         messages::internalError(asyncResp->res);
581e13c2760SPrzemyslaw Czarnowski                         return;
582e13c2760SPrzemyslaw Czarnowski                     }
583e13c2760SPrzemyslaw Czarnowski                 },
584e13c2760SPrzemyslaw Czarnowski                 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
585e13c2760SPrzemyslaw Czarnowski                 "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
586e13c2760SPrzemyslaw Czarnowski         }
587e13c2760SPrzemyslaw Czarnowski     }
588e13c2760SPrzemyslaw Czarnowski };
589e13c2760SPrzemyslaw Czarnowski 
590107077deSPrzemyslaw Czarnowski class VirtualMediaCollection : public Node
591107077deSPrzemyslaw Czarnowski {
592107077deSPrzemyslaw Czarnowski   public:
593107077deSPrzemyslaw Czarnowski     /*
594107077deSPrzemyslaw Czarnowski      * Default Constructor
595107077deSPrzemyslaw Czarnowski      */
596107077deSPrzemyslaw Czarnowski     VirtualMediaCollection(CrowApp &app) :
597107077deSPrzemyslaw Czarnowski         Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/", std::string())
598107077deSPrzemyslaw Czarnowski     {
599107077deSPrzemyslaw Czarnowski         entityPrivileges = {
600107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
601107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
602107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
603107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
604107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
605107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
606107077deSPrzemyslaw Czarnowski     }
607107077deSPrzemyslaw Czarnowski 
608107077deSPrzemyslaw Czarnowski   private:
609107077deSPrzemyslaw Czarnowski     /**
610107077deSPrzemyslaw Czarnowski      * Functions triggers appropriate requests on DBus
611107077deSPrzemyslaw Czarnowski      */
612107077deSPrzemyslaw Czarnowski     void doGet(crow::Response &res, const crow::Request &req,
613107077deSPrzemyslaw Czarnowski                const std::vector<std::string> &params) override
614107077deSPrzemyslaw Czarnowski     {
615107077deSPrzemyslaw Czarnowski         auto asyncResp = std::make_shared<AsyncResp>(res);
616107077deSPrzemyslaw Czarnowski 
617107077deSPrzemyslaw Czarnowski         // Check if there is required param, truly entering this shall be
618107077deSPrzemyslaw Czarnowski         // impossible
619107077deSPrzemyslaw Czarnowski         if (params.size() != 1)
620107077deSPrzemyslaw Czarnowski         {
621107077deSPrzemyslaw Czarnowski             messages::internalError(res);
622107077deSPrzemyslaw Czarnowski 
623107077deSPrzemyslaw Czarnowski             return;
624107077deSPrzemyslaw Czarnowski         }
625107077deSPrzemyslaw Czarnowski 
626107077deSPrzemyslaw Czarnowski         const std::string &name = params[0];
627107077deSPrzemyslaw Czarnowski 
628107077deSPrzemyslaw Czarnowski         if (name != "bmc")
629107077deSPrzemyslaw Czarnowski         {
630107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
631107077deSPrzemyslaw Czarnowski 
632107077deSPrzemyslaw Czarnowski             return;
633107077deSPrzemyslaw Czarnowski         }
634107077deSPrzemyslaw Czarnowski 
635107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.type"] =
636107077deSPrzemyslaw Czarnowski             "#VirtualMediaCollection.VirtualMediaCollection";
637107077deSPrzemyslaw Czarnowski         res.jsonValue["Name"] = "Virtual Media Services";
638107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.id"] =
639107077deSPrzemyslaw Czarnowski             "/redfish/v1/Managers/" + name + "/VirtualMedia/";
640107077deSPrzemyslaw Czarnowski 
641107077deSPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
642107077deSPrzemyslaw Czarnowski             [asyncResp, name](const boost::system::error_code ec,
643107077deSPrzemyslaw Czarnowski                               const GetObjectType &getObjectType) {
644107077deSPrzemyslaw Czarnowski                 if (ec)
645107077deSPrzemyslaw Czarnowski                 {
646107077deSPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
647107077deSPrzemyslaw Czarnowski                                      << ec;
648107077deSPrzemyslaw Czarnowski                     messages::internalError(asyncResp->res);
649107077deSPrzemyslaw Czarnowski 
650107077deSPrzemyslaw Czarnowski                     return;
651107077deSPrzemyslaw Czarnowski                 }
652107077deSPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
653107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
654107077deSPrzemyslaw Czarnowski 
655107077deSPrzemyslaw Czarnowski                 getVmResourceList(asyncResp, service, name);
656107077deSPrzemyslaw Czarnowski             },
657107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
658107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
659107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
660107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
661107077deSPrzemyslaw Czarnowski     }
662107077deSPrzemyslaw Czarnowski };
663107077deSPrzemyslaw Czarnowski 
664107077deSPrzemyslaw Czarnowski class VirtualMedia : public Node
665107077deSPrzemyslaw Czarnowski {
666107077deSPrzemyslaw Czarnowski   public:
667107077deSPrzemyslaw Czarnowski     /*
668107077deSPrzemyslaw Czarnowski      * Default Constructor
669107077deSPrzemyslaw Czarnowski      */
670107077deSPrzemyslaw Czarnowski     VirtualMedia(CrowApp &app) :
671107077deSPrzemyslaw Czarnowski         Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/",
672107077deSPrzemyslaw Czarnowski              std::string(), std::string())
673107077deSPrzemyslaw Czarnowski     {
674107077deSPrzemyslaw Czarnowski         entityPrivileges = {
675107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
676107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
677107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
678107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
679107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
680107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
681107077deSPrzemyslaw Czarnowski     }
682107077deSPrzemyslaw Czarnowski 
683107077deSPrzemyslaw Czarnowski   private:
684107077deSPrzemyslaw Czarnowski     /**
685107077deSPrzemyslaw Czarnowski      * Functions triggers appropriate requests on DBus
686107077deSPrzemyslaw Czarnowski      */
687107077deSPrzemyslaw Czarnowski     void doGet(crow::Response &res, const crow::Request &req,
688107077deSPrzemyslaw Czarnowski                const std::vector<std::string> &params) override
689107077deSPrzemyslaw Czarnowski     {
690107077deSPrzemyslaw Czarnowski         // Check if there is required param, truly entering this shall be
691107077deSPrzemyslaw Czarnowski         // impossible
692107077deSPrzemyslaw Czarnowski         if (params.size() != 2)
693107077deSPrzemyslaw Czarnowski         {
694107077deSPrzemyslaw Czarnowski             messages::internalError(res);
695107077deSPrzemyslaw Czarnowski 
696107077deSPrzemyslaw Czarnowski             res.end();
697107077deSPrzemyslaw Czarnowski             return;
698107077deSPrzemyslaw Czarnowski         }
699107077deSPrzemyslaw Czarnowski         const std::string &name = params[0];
700107077deSPrzemyslaw Czarnowski         const std::string &resName = params[1];
701107077deSPrzemyslaw Czarnowski 
702107077deSPrzemyslaw Czarnowski         auto asyncResp = std::make_shared<AsyncResp>(res);
703107077deSPrzemyslaw Czarnowski 
704107077deSPrzemyslaw Czarnowski         if (name != "bmc")
705107077deSPrzemyslaw Czarnowski         {
706107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
707107077deSPrzemyslaw Czarnowski 
708107077deSPrzemyslaw Czarnowski             return;
709107077deSPrzemyslaw Czarnowski         }
710107077deSPrzemyslaw Czarnowski 
711107077deSPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
712107077deSPrzemyslaw Czarnowski             [asyncResp, name, resName](const boost::system::error_code ec,
713107077deSPrzemyslaw Czarnowski                                        const GetObjectType &getObjectType) {
714107077deSPrzemyslaw Czarnowski                 if (ec)
715107077deSPrzemyslaw Czarnowski                 {
716107077deSPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
717107077deSPrzemyslaw Czarnowski                                      << ec;
718107077deSPrzemyslaw Czarnowski                     messages::internalError(asyncResp->res);
719107077deSPrzemyslaw Czarnowski 
720107077deSPrzemyslaw Czarnowski                     return;
721107077deSPrzemyslaw Czarnowski                 }
722107077deSPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
723107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
724107077deSPrzemyslaw Czarnowski 
725107077deSPrzemyslaw Czarnowski                 getVmData(asyncResp, service, name, resName);
726107077deSPrzemyslaw Czarnowski             },
727107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
728107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
729107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
730107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
731107077deSPrzemyslaw Czarnowski     }
732107077deSPrzemyslaw Czarnowski };
733107077deSPrzemyslaw Czarnowski 
734107077deSPrzemyslaw Czarnowski } // namespace redfish
735