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