xref: /openbmc/bmcweb/features/redfish/lib/virtual_media.hpp (revision 107077def176ad4a29557fae353de9bb00381ca9)
1*107077deSPrzemyslaw Czarnowski /*
2*107077deSPrzemyslaw Czarnowski // Copyright (c) 2018 Intel Corporation
3*107077deSPrzemyslaw Czarnowski //
4*107077deSPrzemyslaw Czarnowski // Licensed under the Apache License, Version 2.0 (the "License");
5*107077deSPrzemyslaw Czarnowski // you may not use this file except in compliance with the License.
6*107077deSPrzemyslaw Czarnowski // You may obtain a copy of the License at
7*107077deSPrzemyslaw Czarnowski //
8*107077deSPrzemyslaw Czarnowski //      http://www.apache.org/licenses/LICENSE-2.0
9*107077deSPrzemyslaw Czarnowski //
10*107077deSPrzemyslaw Czarnowski // Unless required by applicable law or agreed to in writing, software
11*107077deSPrzemyslaw Czarnowski // distributed under the License is distributed on an "AS IS" BASIS,
12*107077deSPrzemyslaw Czarnowski // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*107077deSPrzemyslaw Czarnowski // See the License for the specific language governing permissions and
14*107077deSPrzemyslaw Czarnowski // limitations under the License.
15*107077deSPrzemyslaw Czarnowski */
16*107077deSPrzemyslaw Czarnowski #pragma once
17*107077deSPrzemyslaw Czarnowski 
18*107077deSPrzemyslaw Czarnowski #include <boost/container/flat_map.hpp>
19*107077deSPrzemyslaw Czarnowski #include <node.hpp>
20*107077deSPrzemyslaw Czarnowski #include <utils/json_utils.hpp>
21*107077deSPrzemyslaw Czarnowski // for GetObjectType and ManagedObjectType
22*107077deSPrzemyslaw Czarnowski #include <../lib/account_service.hpp>
23*107077deSPrzemyslaw Czarnowski 
24*107077deSPrzemyslaw Czarnowski namespace redfish
25*107077deSPrzemyslaw Czarnowski 
26*107077deSPrzemyslaw Czarnowski {
27*107077deSPrzemyslaw Czarnowski 
28*107077deSPrzemyslaw Czarnowski /**
29*107077deSPrzemyslaw Czarnowski  * @brief Read all known properties from VM object interfaces
30*107077deSPrzemyslaw Czarnowski  */
31*107077deSPrzemyslaw Czarnowski static void vmParseInterfaceObject(const DbusInterfaceType &interface,
32*107077deSPrzemyslaw Czarnowski                                    std::shared_ptr<AsyncResp> aResp)
33*107077deSPrzemyslaw Czarnowski {
34*107077deSPrzemyslaw Czarnowski     const auto mountPointIface =
35*107077deSPrzemyslaw Czarnowski         interface.find("xyz.openbmc_project.VirtualMedia.MountPoint");
36*107077deSPrzemyslaw Czarnowski     if (mountPointIface == interface.cend())
37*107077deSPrzemyslaw Czarnowski     {
38*107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Interface MountPoint not found";
39*107077deSPrzemyslaw Czarnowski         return;
40*107077deSPrzemyslaw Czarnowski     }
41*107077deSPrzemyslaw Czarnowski 
42*107077deSPrzemyslaw Czarnowski     const auto processIface =
43*107077deSPrzemyslaw Czarnowski         interface.find("xyz.openbmc_project.VirtualMedia.Process");
44*107077deSPrzemyslaw Czarnowski     if (processIface == interface.cend())
45*107077deSPrzemyslaw Czarnowski     {
46*107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Interface Process not found";
47*107077deSPrzemyslaw Czarnowski         return;
48*107077deSPrzemyslaw Czarnowski     }
49*107077deSPrzemyslaw Czarnowski 
50*107077deSPrzemyslaw Czarnowski     const auto endpointIdProperty = mountPointIface->second.find("EndpointId");
51*107077deSPrzemyslaw Czarnowski     if (endpointIdProperty == mountPointIface->second.cend())
52*107077deSPrzemyslaw Czarnowski     {
53*107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Property EndpointId not found";
54*107077deSPrzemyslaw Czarnowski         return;
55*107077deSPrzemyslaw Czarnowski     }
56*107077deSPrzemyslaw Czarnowski 
57*107077deSPrzemyslaw Czarnowski     const auto activeProperty = processIface->second.find("Active");
58*107077deSPrzemyslaw Czarnowski     if (activeProperty == processIface->second.cend())
59*107077deSPrzemyslaw Czarnowski     {
60*107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Property Active not found";
61*107077deSPrzemyslaw Czarnowski         return;
62*107077deSPrzemyslaw Czarnowski     }
63*107077deSPrzemyslaw Czarnowski 
64*107077deSPrzemyslaw Czarnowski     const bool *activeValue = std::get_if<bool>(&activeProperty->second);
65*107077deSPrzemyslaw Czarnowski     if (!activeValue)
66*107077deSPrzemyslaw Czarnowski     {
67*107077deSPrzemyslaw Czarnowski         BMCWEB_LOG_DEBUG << "Value Active not found";
68*107077deSPrzemyslaw Czarnowski         return;
69*107077deSPrzemyslaw Czarnowski     }
70*107077deSPrzemyslaw Czarnowski 
71*107077deSPrzemyslaw Czarnowski     const std::string *endpointIdValue =
72*107077deSPrzemyslaw Czarnowski         std::get_if<std::string>(&endpointIdProperty->second);
73*107077deSPrzemyslaw Czarnowski     if (endpointIdValue)
74*107077deSPrzemyslaw Czarnowski     {
75*107077deSPrzemyslaw Czarnowski         if (!endpointIdValue->empty())
76*107077deSPrzemyslaw Czarnowski         {
77*107077deSPrzemyslaw Czarnowski             // Proxy mode
78*107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["Oem"]["WebSocketEndpoint"] = *endpointIdValue;
79*107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["TransferProtocolType"] = "OEM";
80*107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["Inserted"] = *activeValue;
81*107077deSPrzemyslaw Czarnowski             if (*activeValue == true)
82*107077deSPrzemyslaw Czarnowski             {
83*107077deSPrzemyslaw Czarnowski                 aResp->res.jsonValue["ConnectedVia"] = "Applet";
84*107077deSPrzemyslaw Czarnowski             }
85*107077deSPrzemyslaw Czarnowski         }
86*107077deSPrzemyslaw Czarnowski         else
87*107077deSPrzemyslaw Czarnowski         {
88*107077deSPrzemyslaw Czarnowski             // Legacy mode
89*107077deSPrzemyslaw Czarnowski             const auto imageUrlProperty =
90*107077deSPrzemyslaw Czarnowski                 mountPointIface->second.find("ImageURL");
91*107077deSPrzemyslaw Czarnowski             if (imageUrlProperty != processIface->second.cend())
92*107077deSPrzemyslaw Czarnowski             {
93*107077deSPrzemyslaw Czarnowski                 const std::string *imageUrlValue =
94*107077deSPrzemyslaw Czarnowski                     std::get_if<std::string>(&imageUrlProperty->second);
95*107077deSPrzemyslaw Czarnowski                 if (imageUrlValue && !imageUrlValue->empty())
96*107077deSPrzemyslaw Czarnowski                 {
97*107077deSPrzemyslaw Czarnowski                     aResp->res.jsonValue["ImageName"] = *imageUrlValue;
98*107077deSPrzemyslaw Czarnowski                     aResp->res.jsonValue["Inserted"] = *activeValue;
99*107077deSPrzemyslaw Czarnowski                     if (*activeValue == true)
100*107077deSPrzemyslaw Czarnowski                     {
101*107077deSPrzemyslaw Czarnowski                         aResp->res.jsonValue["ConnectedVia"] = "URI";
102*107077deSPrzemyslaw Czarnowski                     }
103*107077deSPrzemyslaw Czarnowski                 }
104*107077deSPrzemyslaw Czarnowski             }
105*107077deSPrzemyslaw Czarnowski         }
106*107077deSPrzemyslaw Czarnowski     }
107*107077deSPrzemyslaw Czarnowski }
108*107077deSPrzemyslaw Czarnowski 
109*107077deSPrzemyslaw Czarnowski /**
110*107077deSPrzemyslaw Czarnowski  * @brief Fill template for Virtual Media Item.
111*107077deSPrzemyslaw Czarnowski  */
112*107077deSPrzemyslaw Czarnowski static nlohmann::json vmItemTemplate(const std::string &name,
113*107077deSPrzemyslaw Czarnowski                                      const std::string &resName)
114*107077deSPrzemyslaw Czarnowski {
115*107077deSPrzemyslaw Czarnowski     nlohmann::json item;
116*107077deSPrzemyslaw Czarnowski     item["@odata.id"] =
117*107077deSPrzemyslaw Czarnowski         "/redfish/v1/Managers/" + name + "/VirtualMedia/" + resName;
118*107077deSPrzemyslaw Czarnowski     item["@odata.type"] = "#VirtualMedia.v1_1_0.VirtualMedia";
119*107077deSPrzemyslaw Czarnowski     item["@odata.context"] = "/redfish/v1/$metadata#VirtualMedia.VirtualMedia";
120*107077deSPrzemyslaw Czarnowski     item["Name"] = "Virtual Removable Media";
121*107077deSPrzemyslaw Czarnowski     item["Id"] = resName;
122*107077deSPrzemyslaw Czarnowski     item["Image"] = nullptr;
123*107077deSPrzemyslaw Czarnowski     item["Inserted"] = nullptr;
124*107077deSPrzemyslaw Czarnowski     item["ImageName"] = nullptr;
125*107077deSPrzemyslaw Czarnowski     item["WriteProtected"] = true;
126*107077deSPrzemyslaw Czarnowski     item["ConnectedVia"] = "NotConnected";
127*107077deSPrzemyslaw Czarnowski     item["MediaTypes"] = {"CD", "USBStick"};
128*107077deSPrzemyslaw Czarnowski     item["TransferMethod"] = "Stream";
129*107077deSPrzemyslaw Czarnowski     item["TransferProtocolType"] = nullptr;
130*107077deSPrzemyslaw Czarnowski     item["Oem"]["WebSocketEndpoint"] = nullptr;
131*107077deSPrzemyslaw Czarnowski 
132*107077deSPrzemyslaw Czarnowski     return item;
133*107077deSPrzemyslaw Czarnowski }
134*107077deSPrzemyslaw Czarnowski 
135*107077deSPrzemyslaw Czarnowski /**
136*107077deSPrzemyslaw Czarnowski  *  @brief Fills collection data
137*107077deSPrzemyslaw Czarnowski  */
138*107077deSPrzemyslaw Czarnowski static void getVmResourceList(std::shared_ptr<AsyncResp> aResp,
139*107077deSPrzemyslaw Czarnowski                               const std::string &service,
140*107077deSPrzemyslaw Czarnowski                               const std::string &name)
141*107077deSPrzemyslaw Czarnowski {
142*107077deSPrzemyslaw Czarnowski     BMCWEB_LOG_DEBUG << "Get available Virtual Media resources.";
143*107077deSPrzemyslaw Czarnowski     crow::connections::systemBus->async_method_call(
144*107077deSPrzemyslaw Czarnowski         [name, aResp{std::move(aResp)}](const boost::system::error_code ec,
145*107077deSPrzemyslaw Czarnowski                                         ManagedObjectType &subtree) {
146*107077deSPrzemyslaw Czarnowski             if (ec)
147*107077deSPrzemyslaw Czarnowski             {
148*107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "DBUS response error";
149*107077deSPrzemyslaw Czarnowski                 return;
150*107077deSPrzemyslaw Czarnowski             }
151*107077deSPrzemyslaw Czarnowski             nlohmann::json &members = aResp->res.jsonValue["Members"];
152*107077deSPrzemyslaw Czarnowski             members = nlohmann::json::array();
153*107077deSPrzemyslaw Czarnowski 
154*107077deSPrzemyslaw Czarnowski             for (const auto &object : subtree)
155*107077deSPrzemyslaw Czarnowski             {
156*107077deSPrzemyslaw Czarnowski                 nlohmann::json item;
157*107077deSPrzemyslaw Czarnowski                 const std::string &path =
158*107077deSPrzemyslaw Czarnowski                     static_cast<const std::string &>(object.first);
159*107077deSPrzemyslaw Czarnowski                 std::size_t lastIndex = path.rfind("/");
160*107077deSPrzemyslaw Czarnowski                 if (lastIndex == std::string::npos)
161*107077deSPrzemyslaw Czarnowski                 {
162*107077deSPrzemyslaw Czarnowski                     continue;
163*107077deSPrzemyslaw Czarnowski                 }
164*107077deSPrzemyslaw Czarnowski 
165*107077deSPrzemyslaw Czarnowski                 lastIndex += 1;
166*107077deSPrzemyslaw Czarnowski 
167*107077deSPrzemyslaw Czarnowski                 item["@odata.id"] = "/redfish/v1/Managers/" + name +
168*107077deSPrzemyslaw Czarnowski                                     "/VirtualMedia/" + path.substr(lastIndex);
169*107077deSPrzemyslaw Czarnowski 
170*107077deSPrzemyslaw Czarnowski                 members.emplace_back(std::move(item));
171*107077deSPrzemyslaw Czarnowski             }
172*107077deSPrzemyslaw Czarnowski             aResp->res.jsonValue["Members@odata.count"] = members.size();
173*107077deSPrzemyslaw Czarnowski         },
174*107077deSPrzemyslaw Czarnowski         service, "/xyz/openbmc_project/VirtualMedia",
175*107077deSPrzemyslaw Czarnowski         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
176*107077deSPrzemyslaw Czarnowski }
177*107077deSPrzemyslaw Czarnowski 
178*107077deSPrzemyslaw Czarnowski /**
179*107077deSPrzemyslaw Czarnowski  *  @brief Fills data for specific resource
180*107077deSPrzemyslaw Czarnowski  */
181*107077deSPrzemyslaw Czarnowski static void getVmData(std::shared_ptr<AsyncResp> aResp,
182*107077deSPrzemyslaw Czarnowski                       const std::string &service, const std::string &name,
183*107077deSPrzemyslaw Czarnowski                       const std::string &resName)
184*107077deSPrzemyslaw Czarnowski {
185*107077deSPrzemyslaw Czarnowski     BMCWEB_LOG_DEBUG << "Get Virtual Media resource data.";
186*107077deSPrzemyslaw Czarnowski 
187*107077deSPrzemyslaw Czarnowski     crow::connections::systemBus->async_method_call(
188*107077deSPrzemyslaw Czarnowski         [resName, name, aResp](const boost::system::error_code ec,
189*107077deSPrzemyslaw Czarnowski                                ManagedObjectType &subtree) {
190*107077deSPrzemyslaw Czarnowski             if (ec)
191*107077deSPrzemyslaw Czarnowski             {
192*107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "DBUS response error";
193*107077deSPrzemyslaw Czarnowski                 return;
194*107077deSPrzemyslaw Czarnowski             }
195*107077deSPrzemyslaw Czarnowski 
196*107077deSPrzemyslaw Czarnowski             for (auto &item : subtree)
197*107077deSPrzemyslaw Czarnowski             {
198*107077deSPrzemyslaw Czarnowski                 const std::string &path =
199*107077deSPrzemyslaw Czarnowski                     static_cast<const std::string &>(item.first);
200*107077deSPrzemyslaw Czarnowski 
201*107077deSPrzemyslaw Czarnowski                 std::size_t lastItem = path.rfind("/");
202*107077deSPrzemyslaw Czarnowski                 if (lastItem == std::string::npos)
203*107077deSPrzemyslaw Czarnowski                 {
204*107077deSPrzemyslaw Czarnowski                     continue;
205*107077deSPrzemyslaw Czarnowski                 }
206*107077deSPrzemyslaw Czarnowski 
207*107077deSPrzemyslaw Czarnowski                 if (path.substr(lastItem + 1) != resName)
208*107077deSPrzemyslaw Czarnowski                 {
209*107077deSPrzemyslaw Czarnowski                     continue;
210*107077deSPrzemyslaw Czarnowski                 }
211*107077deSPrzemyslaw Czarnowski 
212*107077deSPrzemyslaw Czarnowski                 aResp->res.jsonValue = vmItemTemplate(name, resName);
213*107077deSPrzemyslaw Czarnowski 
214*107077deSPrzemyslaw Czarnowski                 vmParseInterfaceObject(item.second, aResp);
215*107077deSPrzemyslaw Czarnowski 
216*107077deSPrzemyslaw Czarnowski                 return;
217*107077deSPrzemyslaw Czarnowski             }
218*107077deSPrzemyslaw Czarnowski 
219*107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(
220*107077deSPrzemyslaw Czarnowski                 aResp->res, "#VirtualMedia.v1_1_0.VirtualMedia", resName);
221*107077deSPrzemyslaw Czarnowski         },
222*107077deSPrzemyslaw Czarnowski         service, "/xyz/openbmc_project/VirtualMedia",
223*107077deSPrzemyslaw Czarnowski         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
224*107077deSPrzemyslaw Czarnowski }
225*107077deSPrzemyslaw Czarnowski 
226*107077deSPrzemyslaw Czarnowski class VirtualMediaCollection : public Node
227*107077deSPrzemyslaw Czarnowski {
228*107077deSPrzemyslaw Czarnowski   public:
229*107077deSPrzemyslaw Czarnowski     /*
230*107077deSPrzemyslaw Czarnowski      * Default Constructor
231*107077deSPrzemyslaw Czarnowski      */
232*107077deSPrzemyslaw Czarnowski     VirtualMediaCollection(CrowApp &app) :
233*107077deSPrzemyslaw Czarnowski         Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/", std::string())
234*107077deSPrzemyslaw Czarnowski     {
235*107077deSPrzemyslaw Czarnowski         entityPrivileges = {
236*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
237*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
238*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
239*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
240*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
241*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
242*107077deSPrzemyslaw Czarnowski     }
243*107077deSPrzemyslaw Czarnowski 
244*107077deSPrzemyslaw Czarnowski   private:
245*107077deSPrzemyslaw Czarnowski     /**
246*107077deSPrzemyslaw Czarnowski      * Functions triggers appropriate requests on DBus
247*107077deSPrzemyslaw Czarnowski      */
248*107077deSPrzemyslaw Czarnowski     void doGet(crow::Response &res, const crow::Request &req,
249*107077deSPrzemyslaw Czarnowski                const std::vector<std::string> &params) override
250*107077deSPrzemyslaw Czarnowski     {
251*107077deSPrzemyslaw Czarnowski         auto asyncResp = std::make_shared<AsyncResp>(res);
252*107077deSPrzemyslaw Czarnowski 
253*107077deSPrzemyslaw Czarnowski         // Check if there is required param, truly entering this shall be
254*107077deSPrzemyslaw Czarnowski         // impossible
255*107077deSPrzemyslaw Czarnowski         if (params.size() != 1)
256*107077deSPrzemyslaw Czarnowski         {
257*107077deSPrzemyslaw Czarnowski             messages::internalError(res);
258*107077deSPrzemyslaw Czarnowski 
259*107077deSPrzemyslaw Czarnowski             return;
260*107077deSPrzemyslaw Czarnowski         }
261*107077deSPrzemyslaw Czarnowski 
262*107077deSPrzemyslaw Czarnowski         const std::string &name = params[0];
263*107077deSPrzemyslaw Czarnowski 
264*107077deSPrzemyslaw Czarnowski         if (name != "bmc")
265*107077deSPrzemyslaw Czarnowski         {
266*107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
267*107077deSPrzemyslaw Czarnowski 
268*107077deSPrzemyslaw Czarnowski             return;
269*107077deSPrzemyslaw Czarnowski         }
270*107077deSPrzemyslaw Czarnowski 
271*107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.type"] =
272*107077deSPrzemyslaw Czarnowski             "#VirtualMediaCollection.VirtualMediaCollection";
273*107077deSPrzemyslaw Czarnowski         res.jsonValue["Name"] = "Virtual Media Services";
274*107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.context"] =
275*107077deSPrzemyslaw Czarnowski             "/redfish/v1/"
276*107077deSPrzemyslaw Czarnowski             "$metadata#VirtualMediaCollection.VirtualMediaCollection";
277*107077deSPrzemyslaw Czarnowski         res.jsonValue["@odata.id"] =
278*107077deSPrzemyslaw Czarnowski             "/redfish/v1/Managers/" + name + "/VirtualMedia/";
279*107077deSPrzemyslaw Czarnowski 
280*107077deSPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
281*107077deSPrzemyslaw Czarnowski             [asyncResp, name](const boost::system::error_code ec,
282*107077deSPrzemyslaw Czarnowski                               const GetObjectType &getObjectType) {
283*107077deSPrzemyslaw Czarnowski                 if (ec)
284*107077deSPrzemyslaw Czarnowski                 {
285*107077deSPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
286*107077deSPrzemyslaw Czarnowski                                      << ec;
287*107077deSPrzemyslaw Czarnowski                     messages::internalError(asyncResp->res);
288*107077deSPrzemyslaw Czarnowski 
289*107077deSPrzemyslaw Czarnowski                     return;
290*107077deSPrzemyslaw Czarnowski                 }
291*107077deSPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
292*107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
293*107077deSPrzemyslaw Czarnowski 
294*107077deSPrzemyslaw Czarnowski                 getVmResourceList(asyncResp, service, name);
295*107077deSPrzemyslaw Czarnowski             },
296*107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
297*107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
298*107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
299*107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
300*107077deSPrzemyslaw Czarnowski     }
301*107077deSPrzemyslaw Czarnowski };
302*107077deSPrzemyslaw Czarnowski 
303*107077deSPrzemyslaw Czarnowski class VirtualMedia : public Node
304*107077deSPrzemyslaw Czarnowski {
305*107077deSPrzemyslaw Czarnowski   public:
306*107077deSPrzemyslaw Czarnowski     /*
307*107077deSPrzemyslaw Czarnowski      * Default Constructor
308*107077deSPrzemyslaw Czarnowski      */
309*107077deSPrzemyslaw Czarnowski     VirtualMedia(CrowApp &app) :
310*107077deSPrzemyslaw Czarnowski         Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/",
311*107077deSPrzemyslaw Czarnowski              std::string(), std::string())
312*107077deSPrzemyslaw Czarnowski     {
313*107077deSPrzemyslaw Czarnowski         entityPrivileges = {
314*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::get, {{"Login"}}},
315*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::head, {{"Login"}}},
316*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
317*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
318*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
319*107077deSPrzemyslaw Czarnowski             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
320*107077deSPrzemyslaw Czarnowski     }
321*107077deSPrzemyslaw Czarnowski 
322*107077deSPrzemyslaw Czarnowski   private:
323*107077deSPrzemyslaw Czarnowski     /**
324*107077deSPrzemyslaw Czarnowski      * Functions triggers appropriate requests on DBus
325*107077deSPrzemyslaw Czarnowski      */
326*107077deSPrzemyslaw Czarnowski     void doGet(crow::Response &res, const crow::Request &req,
327*107077deSPrzemyslaw Czarnowski                const std::vector<std::string> &params) override
328*107077deSPrzemyslaw Czarnowski     {
329*107077deSPrzemyslaw Czarnowski         // Check if there is required param, truly entering this shall be
330*107077deSPrzemyslaw Czarnowski         // impossible
331*107077deSPrzemyslaw Czarnowski         if (params.size() != 2)
332*107077deSPrzemyslaw Czarnowski         {
333*107077deSPrzemyslaw Czarnowski             messages::internalError(res);
334*107077deSPrzemyslaw Czarnowski 
335*107077deSPrzemyslaw Czarnowski             res.end();
336*107077deSPrzemyslaw Czarnowski             return;
337*107077deSPrzemyslaw Czarnowski         }
338*107077deSPrzemyslaw Czarnowski         const std::string &name = params[0];
339*107077deSPrzemyslaw Czarnowski         const std::string &resName = params[1];
340*107077deSPrzemyslaw Czarnowski 
341*107077deSPrzemyslaw Czarnowski         auto asyncResp = std::make_shared<AsyncResp>(res);
342*107077deSPrzemyslaw Czarnowski 
343*107077deSPrzemyslaw Czarnowski         if (name != "bmc")
344*107077deSPrzemyslaw Czarnowski         {
345*107077deSPrzemyslaw Czarnowski             messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
346*107077deSPrzemyslaw Czarnowski 
347*107077deSPrzemyslaw Czarnowski             return;
348*107077deSPrzemyslaw Czarnowski         }
349*107077deSPrzemyslaw Czarnowski 
350*107077deSPrzemyslaw Czarnowski         crow::connections::systemBus->async_method_call(
351*107077deSPrzemyslaw Czarnowski             [asyncResp, name, resName](const boost::system::error_code ec,
352*107077deSPrzemyslaw Czarnowski                                        const GetObjectType &getObjectType) {
353*107077deSPrzemyslaw Czarnowski                 if (ec)
354*107077deSPrzemyslaw Czarnowski                 {
355*107077deSPrzemyslaw Czarnowski                     BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
356*107077deSPrzemyslaw Czarnowski                                      << ec;
357*107077deSPrzemyslaw Czarnowski                     messages::internalError(asyncResp->res);
358*107077deSPrzemyslaw Czarnowski 
359*107077deSPrzemyslaw Czarnowski                     return;
360*107077deSPrzemyslaw Czarnowski                 }
361*107077deSPrzemyslaw Czarnowski                 std::string service = getObjectType.begin()->first;
362*107077deSPrzemyslaw Czarnowski                 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
363*107077deSPrzemyslaw Czarnowski 
364*107077deSPrzemyslaw Czarnowski                 getVmData(asyncResp, service, name, resName);
365*107077deSPrzemyslaw Czarnowski             },
366*107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper",
367*107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/object_mapper",
368*107077deSPrzemyslaw Czarnowski             "xyz.openbmc_project.ObjectMapper", "GetObject",
369*107077deSPrzemyslaw Czarnowski             "/xyz/openbmc_project/VirtualMedia", std::array<const char *, 0>());
370*107077deSPrzemyslaw Czarnowski     }
371*107077deSPrzemyslaw Czarnowski };
372*107077deSPrzemyslaw Czarnowski 
373*107077deSPrzemyslaw Czarnowski } // namespace redfish
374