1107077deSPrzemyslaw Czarnowski /*
26be832e2SEd Tanous Copyright (c) 2018 Intel Corporation
36be832e2SEd Tanous
46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License");
56be832e2SEd Tanous you may not use this file except in compliance with the License.
66be832e2SEd Tanous You may obtain a copy of the License at
76be832e2SEd Tanous
86be832e2SEd Tanous http://www.apache.org/licenses/LICENSE-2.0
96be832e2SEd Tanous
106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software
116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS,
126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136be832e2SEd Tanous See the License for the specific language governing permissions and
146be832e2SEd Tanous limitations under the License.
15107077deSPrzemyslaw Czarnowski */
16107077deSPrzemyslaw Czarnowski #pragma once
17107077deSPrzemyslaw Czarnowski
183ccb3adbSEd Tanous #include "account_service.hpp"
193ccb3adbSEd Tanous #include "app.hpp"
2079fdf63eSPrzemyslaw Czarnowski #include "async_resp.hpp"
2111e8f60dSEd Tanous #include "credential_pipe.hpp"
222b73119cSGeorge Liu #include "dbus_utility.hpp"
23739b87efSEd Tanous #include "generated/enums/virtual_media.hpp"
243ccb3adbSEd Tanous #include "query.hpp"
253ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
263ccb3adbSEd Tanous #include "utils/json_utils.hpp"
273ccb3adbSEd Tanous
28ef4c65b7SEd Tanous #include <boost/url/format.hpp>
299e319cf0SAnna Platash #include <boost/url/url_view.hpp>
304a7fbefdSEd Tanous #include <boost/url/url_view_base.hpp>
31107077deSPrzemyslaw Czarnowski
322b73119cSGeorge Liu #include <array>
333544d2a7SEd Tanous #include <ranges>
342b73119cSGeorge Liu #include <string_view>
352b73119cSGeorge Liu
36107077deSPrzemyslaw Czarnowski namespace redfish
37107077deSPrzemyslaw Czarnowski {
38365a73f4SEd Tanous
39365a73f4SEd Tanous enum class VmMode
40365a73f4SEd Tanous {
41365a73f4SEd Tanous Invalid,
42365a73f4SEd Tanous Legacy,
43365a73f4SEd Tanous Proxy
44365a73f4SEd Tanous };
45365a73f4SEd Tanous
parseObjectPathAndGetMode(const sdbusplus::message::object_path & itemPath,const std::string & resName)46bd79bce8SPatrick Williams inline VmMode parseObjectPathAndGetMode(
47bd79bce8SPatrick Williams const sdbusplus::message::object_path& itemPath, const std::string& resName)
48365a73f4SEd Tanous {
49365a73f4SEd Tanous std::string thisPath = itemPath.filename();
5062598e31SEd Tanous BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
51365a73f4SEd Tanous
52365a73f4SEd Tanous if (thisPath.empty())
53365a73f4SEd Tanous {
54365a73f4SEd Tanous return VmMode::Invalid;
55365a73f4SEd Tanous }
56365a73f4SEd Tanous
57365a73f4SEd Tanous if (thisPath != resName)
58365a73f4SEd Tanous {
59365a73f4SEd Tanous return VmMode::Invalid;
60365a73f4SEd Tanous }
61365a73f4SEd Tanous
62365a73f4SEd Tanous auto mode = itemPath.parent_path();
63365a73f4SEd Tanous auto type = mode.parent_path();
64365a73f4SEd Tanous
65365a73f4SEd Tanous if (mode.filename().empty() || type.filename().empty())
66365a73f4SEd Tanous {
67365a73f4SEd Tanous return VmMode::Invalid;
68365a73f4SEd Tanous }
69365a73f4SEd Tanous
70365a73f4SEd Tanous if (type.filename() != "VirtualMedia")
71365a73f4SEd Tanous {
72365a73f4SEd Tanous return VmMode::Invalid;
73365a73f4SEd Tanous }
74365a73f4SEd Tanous std::string modeStr = mode.filename();
75365a73f4SEd Tanous if (modeStr == "Legacy")
76365a73f4SEd Tanous {
77365a73f4SEd Tanous return VmMode::Legacy;
78365a73f4SEd Tanous }
79365a73f4SEd Tanous if (modeStr == "Proxy")
80365a73f4SEd Tanous {
81365a73f4SEd Tanous return VmMode::Proxy;
82365a73f4SEd Tanous }
83365a73f4SEd Tanous return VmMode::Invalid;
84365a73f4SEd Tanous }
85365a73f4SEd Tanous
8679fdf63eSPrzemyslaw Czarnowski using CheckItemHandler =
8779fdf63eSPrzemyslaw Czarnowski std::function<void(const std::string& service, const std::string& resName,
8879fdf63eSPrzemyslaw Czarnowski const std::shared_ptr<bmcweb::AsyncResp>&,
8970cbdf53SGeorge Liu const std::pair<sdbusplus::message::object_path,
9080f79a40SMichael Shen dbus::utility::DBusInterfacesMap>&)>;
9179fdf63eSPrzemyslaw Czarnowski
92ac106bf6SEd Tanous inline void
findAndParseObject(const std::string & service,const std::string & resName,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,CheckItemHandler && handler)93ac106bf6SEd Tanous findAndParseObject(const std::string& service, const std::string& resName,
94ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9579fdf63eSPrzemyslaw Czarnowski CheckItemHandler&& handler)
9679fdf63eSPrzemyslaw Czarnowski {
975eb468daSGeorge Liu sdbusplus::message::object_path path("/xyz/openbmc_project/VirtualMedia");
985eb468daSGeorge Liu dbus::utility::getManagedObjects(
995eb468daSGeorge Liu service, path,
1008cb2c024SEd Tanous [service, resName, asyncResp, handler = std::move(handler)](
1018cb2c024SEd Tanous const boost::system::error_code& ec,
10270cbdf53SGeorge Liu const dbus::utility::ManagedObjectType& subtree) {
10379fdf63eSPrzemyslaw Czarnowski if (ec)
10479fdf63eSPrzemyslaw Czarnowski {
10562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error");
10679fdf63eSPrzemyslaw Czarnowski
10779fdf63eSPrzemyslaw Czarnowski return;
10879fdf63eSPrzemyslaw Czarnowski }
10979fdf63eSPrzemyslaw Czarnowski
11070cbdf53SGeorge Liu for (const auto& item : subtree)
11179fdf63eSPrzemyslaw Czarnowski {
11279fdf63eSPrzemyslaw Czarnowski VmMode mode = parseObjectPathAndGetMode(item.first, resName);
11379fdf63eSPrzemyslaw Czarnowski if (mode != VmMode::Invalid)
11479fdf63eSPrzemyslaw Czarnowski {
115ac106bf6SEd Tanous handler(service, resName, asyncResp, item);
11679fdf63eSPrzemyslaw Czarnowski return;
11779fdf63eSPrzemyslaw Czarnowski }
11879fdf63eSPrzemyslaw Czarnowski }
11979fdf63eSPrzemyslaw Czarnowski
12062598e31SEd Tanous BMCWEB_LOG_DEBUG("Parent item not found");
121ac106bf6SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found);
1225eb468daSGeorge Liu });
12379fdf63eSPrzemyslaw Czarnowski }
12479fdf63eSPrzemyslaw Czarnowski
1259e319cf0SAnna Platash /**
1269e319cf0SAnna Platash * @brief Function extracts transfer protocol name from URI.
1279e319cf0SAnna Platash */
getTransferProtocolTypeFromUri(const std::string & imageUri)12867df073bSEd Tanous inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
12967df073bSEd Tanous {
1306fd29553SEd Tanous boost::system::result<boost::urls::url_view> url =
131079360aeSEd Tanous boost::urls::parse_uri(imageUri);
13267df073bSEd Tanous if (!url)
13367df073bSEd Tanous {
13467df073bSEd Tanous return "None";
13567df073bSEd Tanous }
136079360aeSEd Tanous std::string_view scheme = url->scheme();
13767df073bSEd Tanous if (scheme == "smb")
13867df073bSEd Tanous {
13967df073bSEd Tanous return "CIFS";
14067df073bSEd Tanous }
14167df073bSEd Tanous if (scheme == "https")
14267df073bSEd Tanous {
14367df073bSEd Tanous return "HTTPS";
14467df073bSEd Tanous }
14567df073bSEd Tanous
14667df073bSEd Tanous return "None";
14767df073bSEd Tanous }
148107077deSPrzemyslaw Czarnowski
149107077deSPrzemyslaw Czarnowski /**
150107077deSPrzemyslaw Czarnowski * @brief Read all known properties from VM object interfaces
151107077deSPrzemyslaw Czarnowski */
15222db1728SEd Tanous inline void
vmParseInterfaceObject(const dbus::utility::DBusInterfacesMap & interfaces,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)15380f79a40SMichael Shen vmParseInterfaceObject(const dbus::utility::DBusInterfacesMap& interfaces,
154ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
155107077deSPrzemyslaw Czarnowski {
1568a592810SEd Tanous for (const auto& [interface, values] : interfaces)
157107077deSPrzemyslaw Czarnowski {
158711ac7a9SEd Tanous if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
159107077deSPrzemyslaw Czarnowski {
160711ac7a9SEd Tanous for (const auto& [property, value] : values)
161107077deSPrzemyslaw Czarnowski {
162711ac7a9SEd Tanous if (property == "EndpointId")
163107077deSPrzemyslaw Czarnowski {
164107077deSPrzemyslaw Czarnowski const std::string* endpointIdValue =
165711ac7a9SEd Tanous std::get_if<std::string>(&value);
166711ac7a9SEd Tanous if (endpointIdValue == nullptr)
167107077deSPrzemyslaw Czarnowski {
168711ac7a9SEd Tanous continue;
169711ac7a9SEd Tanous }
170107077deSPrzemyslaw Czarnowski if (!endpointIdValue->empty())
171107077deSPrzemyslaw Czarnowski {
172107077deSPrzemyslaw Czarnowski // Proxy mode
173ac106bf6SEd Tanous asyncResp->res
174711ac7a9SEd Tanous .jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
175d04ba325SPrzemyslaw Czarnowski *endpointIdValue;
176ac106bf6SEd Tanous asyncResp->res.jsonValue["TransferProtocolType"] =
177ac106bf6SEd Tanous "OEM";
178107077deSPrzemyslaw Czarnowski }
179107077deSPrzemyslaw Czarnowski }
180711ac7a9SEd Tanous if (property == "ImageURL")
181107077deSPrzemyslaw Czarnowski {
182107077deSPrzemyslaw Czarnowski const std::string* imageUrlValue =
183711ac7a9SEd Tanous std::get_if<std::string>(&value);
18426f6976fSEd Tanous if (imageUrlValue != nullptr && !imageUrlValue->empty())
185107077deSPrzemyslaw Czarnowski {
186da4784d8SPrzemyslaw Czarnowski std::filesystem::path filePath = *imageUrlValue;
187da4784d8SPrzemyslaw Czarnowski if (!filePath.has_filename())
188da4784d8SPrzemyslaw Czarnowski {
1899e319cf0SAnna Platash // this will handle https share, which not
1909e319cf0SAnna Platash // necessarily has to have filename given.
191ac106bf6SEd Tanous asyncResp->res.jsonValue["ImageName"] = "";
192da4784d8SPrzemyslaw Czarnowski }
193da4784d8SPrzemyslaw Czarnowski else
194da4784d8SPrzemyslaw Czarnowski {
195ac106bf6SEd Tanous asyncResp->res.jsonValue["ImageName"] =
1969e319cf0SAnna Platash filePath.filename();
197da4784d8SPrzemyslaw Czarnowski }
198da4784d8SPrzemyslaw Czarnowski
199ac106bf6SEd Tanous asyncResp->res.jsonValue["Image"] = *imageUrlValue;
200ac106bf6SEd Tanous asyncResp->res.jsonValue["TransferProtocolType"] =
2019e319cf0SAnna Platash getTransferProtocolTypeFromUri(*imageUrlValue);
2029e319cf0SAnna Platash
203ac106bf6SEd Tanous asyncResp->res.jsonValue["ConnectedVia"] =
204739b87efSEd Tanous virtual_media::ConnectedVia::URI;
205107077deSPrzemyslaw Czarnowski }
206107077deSPrzemyslaw Czarnowski }
207711ac7a9SEd Tanous if (property == "WriteProtected")
2089e319cf0SAnna Platash {
209711ac7a9SEd Tanous const bool* writeProtectedValue = std::get_if<bool>(&value);
210e662eae8SEd Tanous if (writeProtectedValue != nullptr)
2119e319cf0SAnna Platash {
212ac106bf6SEd Tanous asyncResp->res.jsonValue["WriteProtected"] =
2139e319cf0SAnna Platash *writeProtectedValue;
2149e319cf0SAnna Platash }
2159e319cf0SAnna Platash }
2169e319cf0SAnna Platash }
217107077deSPrzemyslaw Czarnowski }
218711ac7a9SEd Tanous if (interface == "xyz.openbmc_project.VirtualMedia.Process")
219711ac7a9SEd Tanous {
220711ac7a9SEd Tanous for (const auto& [property, value] : values)
221711ac7a9SEd Tanous {
222711ac7a9SEd Tanous if (property == "Active")
223711ac7a9SEd Tanous {
224711ac7a9SEd Tanous const bool* activeValue = std::get_if<bool>(&value);
225e662eae8SEd Tanous if (activeValue == nullptr)
226711ac7a9SEd Tanous {
22762598e31SEd Tanous BMCWEB_LOG_DEBUG("Value Active not found");
228711ac7a9SEd Tanous return;
229711ac7a9SEd Tanous }
230ac106bf6SEd Tanous asyncResp->res.jsonValue["Inserted"] = *activeValue;
231711ac7a9SEd Tanous
232e05aec50SEd Tanous if (*activeValue)
233711ac7a9SEd Tanous {
234ac106bf6SEd Tanous asyncResp->res.jsonValue["ConnectedVia"] =
235739b87efSEd Tanous virtual_media::ConnectedVia::Applet;
236711ac7a9SEd Tanous }
237711ac7a9SEd Tanous }
238711ac7a9SEd Tanous }
239711ac7a9SEd Tanous }
240107077deSPrzemyslaw Czarnowski }
241107077deSPrzemyslaw Czarnowski }
242107077deSPrzemyslaw Czarnowski
243107077deSPrzemyslaw Czarnowski /**
244107077deSPrzemyslaw Czarnowski * @brief Fill template for Virtual Media Item.
245107077deSPrzemyslaw Czarnowski */
vmItemTemplate(const std::string & name,const std::string & resName)24622db1728SEd Tanous inline nlohmann::json vmItemTemplate(const std::string& name,
247107077deSPrzemyslaw Czarnowski const std::string& resName)
248107077deSPrzemyslaw Czarnowski {
249107077deSPrzemyslaw Czarnowski nlohmann::json item;
250ef4c65b7SEd Tanous item["@odata.id"] = boost::urls::format(
251ef4c65b7SEd Tanous "/redfish/v1/Managers/{}/VirtualMedia/{}", name, resName);
25222db1728SEd Tanous
253d04ba325SPrzemyslaw Czarnowski item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
254107077deSPrzemyslaw Czarnowski item["Name"] = "Virtual Removable Media";
255107077deSPrzemyslaw Czarnowski item["Id"] = resName;
256107077deSPrzemyslaw Czarnowski item["WriteProtected"] = true;
257739b87efSEd Tanous item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
258613dabeaSEd Tanous item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
259539d8c6bSEd Tanous item["TransferMethod"] = virtual_media::TransferMethod::Stream;
260d04ba325SPrzemyslaw Czarnowski item["Oem"]["OpenBMC"]["@odata.type"] =
261f958ed9cSEd Tanous "#OpenBMCVirtualMedia.v1_0_0.VirtualMedia";
26215b89725SV-Sanjana item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
26315b89725SV-Sanjana "/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
264107077deSPrzemyslaw Czarnowski
265107077deSPrzemyslaw Czarnowski return item;
266107077deSPrzemyslaw Czarnowski }
267107077deSPrzemyslaw Czarnowski
268107077deSPrzemyslaw Czarnowski /**
269107077deSPrzemyslaw Czarnowski * @brief Fills collection data
270107077deSPrzemyslaw Czarnowski */
getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,const std::string & service,const std::string & name)271ac106bf6SEd Tanous inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
272107077deSPrzemyslaw Czarnowski const std::string& service,
273107077deSPrzemyslaw Czarnowski const std::string& name)
274107077deSPrzemyslaw Czarnowski {
27562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available Virtual Media resources.");
2765eb468daSGeorge Liu sdbusplus::message::object_path objPath(
2775eb468daSGeorge Liu "/xyz/openbmc_project/VirtualMedia");
2785eb468daSGeorge Liu dbus::utility::getManagedObjects(
2795eb468daSGeorge Liu service, objPath,
280ac106bf6SEd Tanous [name, asyncResp{std::move(asyncResp)}](
2815e7e2dc5SEd Tanous const boost::system::error_code& ec,
28202cad96eSEd Tanous const dbus::utility::ManagedObjectType& subtree) {
283107077deSPrzemyslaw Czarnowski if (ec)
284107077deSPrzemyslaw Czarnowski {
28562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error");
286107077deSPrzemyslaw Czarnowski return;
287107077deSPrzemyslaw Czarnowski }
288ac106bf6SEd Tanous nlohmann::json& members = asyncResp->res.jsonValue["Members"];
289107077deSPrzemyslaw Czarnowski members = nlohmann::json::array();
290107077deSPrzemyslaw Czarnowski
291107077deSPrzemyslaw Czarnowski for (const auto& object : subtree)
292107077deSPrzemyslaw Czarnowski {
293107077deSPrzemyslaw Czarnowski nlohmann::json item;
2942dfd18efSEd Tanous std::string path = object.first.filename();
2952dfd18efSEd Tanous if (path.empty())
296107077deSPrzemyslaw Czarnowski {
297107077deSPrzemyslaw Czarnowski continue;
298107077deSPrzemyslaw Czarnowski }
299107077deSPrzemyslaw Czarnowski
300ef4c65b7SEd Tanous item["@odata.id"] = boost::urls::format(
301ef4c65b7SEd Tanous "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
302107077deSPrzemyslaw Czarnowski members.emplace_back(std::move(item));
303107077deSPrzemyslaw Czarnowski }
304ac106bf6SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = members.size();
3055eb468daSGeorge Liu });
306107077deSPrzemyslaw Czarnowski }
307107077deSPrzemyslaw Czarnowski
30870cbdf53SGeorge Liu inline void
afterGetVmData(const std::string & name,const std::string &,const std::string & resName,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::pair<sdbusplus::message::object_path,dbus::utility::DBusInterfacesMap> & item)30970cbdf53SGeorge Liu afterGetVmData(const std::string& name, const std::string& /*service*/,
31079fdf63eSPrzemyslaw Czarnowski const std::string& resName,
31179fdf63eSPrzemyslaw Czarnowski const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31270cbdf53SGeorge Liu const std::pair<sdbusplus::message::object_path,
31380f79a40SMichael Shen dbus::utility::DBusInterfacesMap>& item)
31479fdf63eSPrzemyslaw Czarnowski {
31579fdf63eSPrzemyslaw Czarnowski VmMode mode = parseObjectPathAndGetMode(item.first, resName);
31679fdf63eSPrzemyslaw Czarnowski if (mode == VmMode::Invalid)
31779fdf63eSPrzemyslaw Czarnowski {
31879fdf63eSPrzemyslaw Czarnowski return;
31979fdf63eSPrzemyslaw Czarnowski }
32079fdf63eSPrzemyslaw Czarnowski
32179fdf63eSPrzemyslaw Czarnowski asyncResp->res.jsonValue = vmItemTemplate(name, resName);
32279fdf63eSPrzemyslaw Czarnowski
32379fdf63eSPrzemyslaw Czarnowski // Check if dbus path is Legacy type
32479fdf63eSPrzemyslaw Czarnowski if (mode == VmMode::Legacy)
32579fdf63eSPrzemyslaw Czarnowski {
326ef4c65b7SEd Tanous asyncResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
327ef4c65b7SEd Tanous ["target"] = boost::urls::format(
328ef4c65b7SEd Tanous "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.InsertMedia",
329ef4c65b7SEd Tanous name, resName);
33079fdf63eSPrzemyslaw Czarnowski }
33179fdf63eSPrzemyslaw Czarnowski
33279fdf63eSPrzemyslaw Czarnowski vmParseInterfaceObject(item.second, asyncResp);
33379fdf63eSPrzemyslaw Czarnowski
334ef4c65b7SEd Tanous asyncResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
335ef4c65b7SEd Tanous ["target"] = boost::urls::format(
336ef4c65b7SEd Tanous "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.EjectMedia",
337ef4c65b7SEd Tanous name, resName);
33879fdf63eSPrzemyslaw Czarnowski }
33979fdf63eSPrzemyslaw Czarnowski
340107077deSPrzemyslaw Czarnowski /**
341107077deSPrzemyslaw Czarnowski * @brief Fills data for specific resource
342107077deSPrzemyslaw Czarnowski */
getVmData(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & service,const std::string & name,const std::string & resName)343ac106bf6SEd Tanous inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
344107077deSPrzemyslaw Czarnowski const std::string& service, const std::string& name,
345107077deSPrzemyslaw Czarnowski const std::string& resName)
346107077deSPrzemyslaw Czarnowski {
34762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Virtual Media resource data.");
348107077deSPrzemyslaw Czarnowski
349ac106bf6SEd Tanous findAndParseObject(service, resName, asyncResp,
35070cbdf53SGeorge Liu std::bind_front(afterGetVmData, name));
351107077deSPrzemyslaw Czarnowski }
352107077deSPrzemyslaw Czarnowski
353e13c2760SPrzemyslaw Czarnowski /**
354c6f4e017SAgata Olender * @brief Transfer protocols supported for InsertMedia action.
355c6f4e017SAgata Olender *
356c6f4e017SAgata Olender */
357c6f4e017SAgata Olender enum class TransferProtocol
358c6f4e017SAgata Olender {
359c6f4e017SAgata Olender https,
360c6f4e017SAgata Olender smb,
361c6f4e017SAgata Olender invalid
362c6f4e017SAgata Olender };
363c6f4e017SAgata Olender
364c6f4e017SAgata Olender /**
365c6f4e017SAgata Olender * @brief Function extracts transfer protocol type from URI.
366c6f4e017SAgata Olender *
367c6f4e017SAgata Olender */
36867df073bSEd Tanous inline std::optional<TransferProtocol>
getTransferProtocolFromUri(const boost::urls::url_view_base & imageUri)3694a7fbefdSEd Tanous getTransferProtocolFromUri(const boost::urls::url_view_base& imageUri)
37067df073bSEd Tanous {
371079360aeSEd Tanous std::string_view scheme = imageUri.scheme();
37267df073bSEd Tanous if (scheme == "smb")
37367df073bSEd Tanous {
37467df073bSEd Tanous return TransferProtocol::smb;
37567df073bSEd Tanous }
37667df073bSEd Tanous if (scheme == "https")
37767df073bSEd Tanous {
37867df073bSEd Tanous return TransferProtocol::https;
37967df073bSEd Tanous }
38067df073bSEd Tanous if (!scheme.empty())
38167df073bSEd Tanous {
38267df073bSEd Tanous return TransferProtocol::invalid;
38367df073bSEd Tanous }
38467df073bSEd Tanous
38567df073bSEd Tanous return {};
38667df073bSEd Tanous }
387c6f4e017SAgata Olender
388c6f4e017SAgata Olender /**
389c6f4e017SAgata Olender * @brief Function convert transfer protocol from string param.
390c6f4e017SAgata Olender *
391c6f4e017SAgata Olender */
getTransferProtocolFromParam(const std::optional<std::string> & transferProtocolType)39222db1728SEd Tanous inline std::optional<TransferProtocol> getTransferProtocolFromParam(
393c6f4e017SAgata Olender const std::optional<std::string>& transferProtocolType)
394c6f4e017SAgata Olender {
395e01d0c36SEd Tanous if (!transferProtocolType)
396c6f4e017SAgata Olender {
397c6f4e017SAgata Olender return {};
398c6f4e017SAgata Olender }
399c6f4e017SAgata Olender
400c6f4e017SAgata Olender if (*transferProtocolType == "CIFS")
401c6f4e017SAgata Olender {
402c6f4e017SAgata Olender return TransferProtocol::smb;
403c6f4e017SAgata Olender }
404c6f4e017SAgata Olender
405c6f4e017SAgata Olender if (*transferProtocolType == "HTTPS")
406c6f4e017SAgata Olender {
407c6f4e017SAgata Olender return TransferProtocol::https;
408c6f4e017SAgata Olender }
409c6f4e017SAgata Olender
410c6f4e017SAgata Olender return TransferProtocol::invalid;
411c6f4e017SAgata Olender }
412c6f4e017SAgata Olender
413c6f4e017SAgata Olender /**
414c6f4e017SAgata Olender * @brief Function extends URI with transfer protocol type.
415c6f4e017SAgata Olender *
416c6f4e017SAgata Olender */
getUriWithTransferProtocol(const std::string & imageUri,const TransferProtocol & transferProtocol)417bd79bce8SPatrick Williams inline std::string getUriWithTransferProtocol(
418bd79bce8SPatrick Williams const std::string& imageUri, const TransferProtocol& transferProtocol)
419c6f4e017SAgata Olender {
420c6f4e017SAgata Olender if (transferProtocol == TransferProtocol::smb)
421c6f4e017SAgata Olender {
422c6f4e017SAgata Olender return "smb://" + imageUri;
423c6f4e017SAgata Olender }
424c6f4e017SAgata Olender
425c6f4e017SAgata Olender if (transferProtocol == TransferProtocol::https)
426c6f4e017SAgata Olender {
427c6f4e017SAgata Olender return "https://" + imageUri;
428c6f4e017SAgata Olender }
429c6f4e017SAgata Olender
430c6f4e017SAgata Olender return imageUri;
431c6f4e017SAgata Olender }
432c6f4e017SAgata Olender
4331f2a40ceSPrzemyslaw Czarnowski struct InsertMediaActionParams
4341f2a40ceSPrzemyslaw Czarnowski {
435120fa86aSPrzemyslaw Czarnowski std::optional<std::string> imageUrl;
4361f2a40ceSPrzemyslaw Czarnowski std::optional<std::string> userName;
4371f2a40ceSPrzemyslaw Czarnowski std::optional<std::string> password;
4381f2a40ceSPrzemyslaw Czarnowski std::optional<std::string> transferMethod;
4391f2a40ceSPrzemyslaw Czarnowski std::optional<std::string> transferProtocolType;
4401f2a40ceSPrzemyslaw Czarnowski std::optional<bool> writeProtected = true;
4411f2a40ceSPrzemyslaw Czarnowski std::optional<bool> inserted;
4421f2a40ceSPrzemyslaw Czarnowski };
4431f2a40ceSPrzemyslaw Czarnowski
444e13c2760SPrzemyslaw Czarnowski /**
445e13c2760SPrzemyslaw Czarnowski * @brief Function transceives data with dbus directly.
446e13c2760SPrzemyslaw Czarnowski *
447e13c2760SPrzemyslaw Czarnowski * All BMC state properties will be retrieved before sending reset request.
448e13c2760SPrzemyslaw Czarnowski */
doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & service,const std::string & name,const std::string & imageUrl,bool rw,std::string && userName,std::string && password)44922db1728SEd Tanous inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
450e13c2760SPrzemyslaw Czarnowski const std::string& service, const std::string& name,
45111e8f60dSEd Tanous const std::string& imageUrl, bool rw,
452988fb7b2SAdrian Ambrożewicz std::string&& userName, std::string&& password)
453e13c2760SPrzemyslaw Czarnowski {
45411e8f60dSEd Tanous int fd = -1;
45511e8f60dSEd Tanous std::shared_ptr<CredentialsPipe> secretPipe;
456988fb7b2SAdrian Ambrożewicz if (!userName.empty() || !password.empty())
457988fb7b2SAdrian Ambrożewicz {
458988fb7b2SAdrian Ambrożewicz // Payload must contain data + NULL delimiters
45911e8f60dSEd Tanous constexpr const size_t secretLimit = 1024;
46011e8f60dSEd Tanous if (userName.size() + password.size() + 2 > secretLimit)
461988fb7b2SAdrian Ambrożewicz {
46262598e31SEd Tanous BMCWEB_LOG_ERROR("Credentials too long to handle");
463988fb7b2SAdrian Ambrożewicz messages::unrecognizedRequestBody(asyncResp->res);
464988fb7b2SAdrian Ambrożewicz return;
465988fb7b2SAdrian Ambrożewicz }
466988fb7b2SAdrian Ambrożewicz
467988fb7b2SAdrian Ambrożewicz // Open pipe
46811e8f60dSEd Tanous secretPipe = std::make_shared<CredentialsPipe>(
46911e8f60dSEd Tanous crow::connections::systemBus->get_io_context());
4703bfa3b29SEd Tanous fd = secretPipe->releaseFd();
471988fb7b2SAdrian Ambrożewicz
472988fb7b2SAdrian Ambrożewicz // Pass secret over pipe
47381ce609eSEd Tanous secretPipe->asyncWrite(
47411e8f60dSEd Tanous std::move(userName), std::move(password),
475bd79bce8SPatrick Williams [asyncResp,
476bd79bce8SPatrick Williams secretPipe](const boost::system::error_code& ec, std::size_t) {
477988fb7b2SAdrian Ambrożewicz if (ec)
478988fb7b2SAdrian Ambrożewicz {
47962598e31SEd Tanous BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
480988fb7b2SAdrian Ambrożewicz messages::internalError(asyncResp->res);
481988fb7b2SAdrian Ambrożewicz }
482988fb7b2SAdrian Ambrożewicz });
483988fb7b2SAdrian Ambrożewicz }
484988fb7b2SAdrian Ambrożewicz
485*e3648032SEd Tanous std::variant<sdbusplus::message::unix_fd> unixFd(
48611e8f60dSEd Tanous std::in_place_type<sdbusplus::message::unix_fd>, fd);
48711e8f60dSEd Tanous
48811e8f60dSEd Tanous sdbusplus::message::object_path path(
48911e8f60dSEd Tanous "/xyz/openbmc_project/VirtualMedia/Legacy");
49011e8f60dSEd Tanous path /= name;
491e13c2760SPrzemyslaw Czarnowski crow::connections::systemBus->async_method_call(
492bd79bce8SPatrick Williams [asyncResp,
493bd79bce8SPatrick Williams secretPipe](const boost::system::error_code& ec, bool success) {
494e13c2760SPrzemyslaw Czarnowski if (ec)
495e13c2760SPrzemyslaw Czarnowski {
49662598e31SEd Tanous BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
497e13c2760SPrzemyslaw Czarnowski messages::internalError(asyncResp->res);
49811e8f60dSEd Tanous return;
499d6da5bebSAdrian Ambrożewicz }
50011e8f60dSEd Tanous if (!success)
501d6da5bebSAdrian Ambrożewicz {
50262598e31SEd Tanous BMCWEB_LOG_ERROR("Service responded with error");
50311e8f60dSEd Tanous messages::internalError(asyncResp->res);
504e13c2760SPrzemyslaw Czarnowski }
505e13c2760SPrzemyslaw Czarnowski },
50611e8f60dSEd Tanous service, path.str, "xyz.openbmc_project.VirtualMedia.Legacy", "Mount",
50711e8f60dSEd Tanous imageUrl, rw, unixFd);
508e13c2760SPrzemyslaw Czarnowski }
509e13c2760SPrzemyslaw Czarnowski
510e13c2760SPrzemyslaw Czarnowski /**
511120fa86aSPrzemyslaw Czarnowski * @brief Function validate parameters of insert media request.
512120fa86aSPrzemyslaw Czarnowski *
513120fa86aSPrzemyslaw Czarnowski */
validateParams(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & service,const std::string & resName,InsertMediaActionParams & actionParams)514120fa86aSPrzemyslaw Czarnowski inline void validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
515120fa86aSPrzemyslaw Czarnowski const std::string& service,
516120fa86aSPrzemyslaw Czarnowski const std::string& resName,
517120fa86aSPrzemyslaw Czarnowski InsertMediaActionParams& actionParams)
518120fa86aSPrzemyslaw Czarnowski {
51962598e31SEd Tanous BMCWEB_LOG_DEBUG("Validation started");
520120fa86aSPrzemyslaw Czarnowski // required param imageUrl must not be empty
521120fa86aSPrzemyslaw Czarnowski if (!actionParams.imageUrl)
522120fa86aSPrzemyslaw Czarnowski {
52362598e31SEd Tanous BMCWEB_LOG_ERROR("Request action parameter Image is empty.");
524120fa86aSPrzemyslaw Czarnowski
525120fa86aSPrzemyslaw Czarnowski messages::propertyValueFormatError(asyncResp->res, "<empty>", "Image");
526120fa86aSPrzemyslaw Czarnowski
527120fa86aSPrzemyslaw Czarnowski return;
528120fa86aSPrzemyslaw Czarnowski }
529120fa86aSPrzemyslaw Czarnowski
530120fa86aSPrzemyslaw Czarnowski // optional param inserted must be true
531e01d0c36SEd Tanous if (actionParams.inserted && !*actionParams.inserted)
532120fa86aSPrzemyslaw Czarnowski {
53362598e31SEd Tanous BMCWEB_LOG_ERROR(
53462598e31SEd Tanous "Request action optional parameter Inserted must be true.");
535120fa86aSPrzemyslaw Czarnowski
536120fa86aSPrzemyslaw Czarnowski messages::actionParameterNotSupported(asyncResp->res, "Inserted",
537120fa86aSPrzemyslaw Czarnowski "InsertMedia");
538120fa86aSPrzemyslaw Czarnowski
539120fa86aSPrzemyslaw Czarnowski return;
540120fa86aSPrzemyslaw Czarnowski }
541120fa86aSPrzemyslaw Czarnowski
542120fa86aSPrzemyslaw Czarnowski // optional param transferMethod must be stream
543e01d0c36SEd Tanous if (actionParams.transferMethod &&
544120fa86aSPrzemyslaw Czarnowski (*actionParams.transferMethod != "Stream"))
545120fa86aSPrzemyslaw Czarnowski {
54662598e31SEd Tanous BMCWEB_LOG_ERROR("Request action optional parameter "
54762598e31SEd Tanous "TransferMethod must be Stream.");
548120fa86aSPrzemyslaw Czarnowski
549120fa86aSPrzemyslaw Czarnowski messages::actionParameterNotSupported(asyncResp->res, "TransferMethod",
550120fa86aSPrzemyslaw Czarnowski "InsertMedia");
551120fa86aSPrzemyslaw Czarnowski
552120fa86aSPrzemyslaw Czarnowski return;
553120fa86aSPrzemyslaw Czarnowski }
5546fd29553SEd Tanous boost::system::result<boost::urls::url_view> url =
555120fa86aSPrzemyslaw Czarnowski boost::urls::parse_uri(*actionParams.imageUrl);
556120fa86aSPrzemyslaw Czarnowski if (!url)
557120fa86aSPrzemyslaw Czarnowski {
558120fa86aSPrzemyslaw Czarnowski messages::actionParameterValueFormatError(
559120fa86aSPrzemyslaw Czarnowski asyncResp->res, *actionParams.imageUrl, "Image", "InsertMedia");
560120fa86aSPrzemyslaw Czarnowski return;
561120fa86aSPrzemyslaw Czarnowski }
562120fa86aSPrzemyslaw Czarnowski std::optional<TransferProtocol> uriTransferProtocolType =
563120fa86aSPrzemyslaw Czarnowski getTransferProtocolFromUri(*url);
564120fa86aSPrzemyslaw Czarnowski
565120fa86aSPrzemyslaw Czarnowski std::optional<TransferProtocol> paramTransferProtocolType =
566120fa86aSPrzemyslaw Czarnowski getTransferProtocolFromParam(actionParams.transferProtocolType);
567120fa86aSPrzemyslaw Czarnowski
568120fa86aSPrzemyslaw Czarnowski // ImageUrl does not contain valid protocol type
569e01d0c36SEd Tanous if (uriTransferProtocolType &&
570e01d0c36SEd Tanous *uriTransferProtocolType == TransferProtocol::invalid)
571120fa86aSPrzemyslaw Czarnowski {
57262598e31SEd Tanous BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
573120fa86aSPrzemyslaw Czarnowski "contain specified protocol type from list: "
57462598e31SEd Tanous "(smb, https).");
575120fa86aSPrzemyslaw Czarnowski
576120fa86aSPrzemyslaw Czarnowski messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
577120fa86aSPrzemyslaw Czarnowski
578120fa86aSPrzemyslaw Czarnowski return;
579120fa86aSPrzemyslaw Czarnowski }
580120fa86aSPrzemyslaw Czarnowski
581120fa86aSPrzemyslaw Czarnowski // transferProtocolType should contain value from list
582e01d0c36SEd Tanous if (paramTransferProtocolType &&
583e01d0c36SEd Tanous *paramTransferProtocolType == TransferProtocol::invalid)
584120fa86aSPrzemyslaw Czarnowski {
58562598e31SEd Tanous BMCWEB_LOG_ERROR("Request action parameter TransferProtocolType "
586120fa86aSPrzemyslaw Czarnowski "must be provided with value from list: "
58762598e31SEd Tanous "(CIFS, HTTPS).");
588120fa86aSPrzemyslaw Czarnowski
589e01d0c36SEd Tanous messages::propertyValueNotInList(
590e01d0c36SEd Tanous asyncResp->res, actionParams.transferProtocolType.value_or(""),
591120fa86aSPrzemyslaw Czarnowski "TransferProtocolType");
592120fa86aSPrzemyslaw Czarnowski return;
593120fa86aSPrzemyslaw Czarnowski }
594120fa86aSPrzemyslaw Czarnowski
595120fa86aSPrzemyslaw Czarnowski // valid transfer protocol not provided either with URI nor param
596e01d0c36SEd Tanous if (!uriTransferProtocolType && !paramTransferProtocolType)
597120fa86aSPrzemyslaw Czarnowski {
59862598e31SEd Tanous BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
599120fa86aSPrzemyslaw Czarnowski "contain specified protocol type or param "
60062598e31SEd Tanous "TransferProtocolType must be provided.");
601120fa86aSPrzemyslaw Czarnowski
602120fa86aSPrzemyslaw Czarnowski messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
603120fa86aSPrzemyslaw Czarnowski
604120fa86aSPrzemyslaw Czarnowski return;
605120fa86aSPrzemyslaw Czarnowski }
606120fa86aSPrzemyslaw Czarnowski
607120fa86aSPrzemyslaw Czarnowski // valid transfer protocol provided both with URI and param
608e01d0c36SEd Tanous if (paramTransferProtocolType && uriTransferProtocolType)
609120fa86aSPrzemyslaw Czarnowski {
610120fa86aSPrzemyslaw Czarnowski // check if protocol is the same for URI and param
611120fa86aSPrzemyslaw Czarnowski if (*paramTransferProtocolType != *uriTransferProtocolType)
612120fa86aSPrzemyslaw Czarnowski {
61362598e31SEd Tanous BMCWEB_LOG_ERROR("Request action parameter "
614120fa86aSPrzemyslaw Czarnowski "TransferProtocolType must contain the "
615120fa86aSPrzemyslaw Czarnowski "same protocol type as protocol type "
61662598e31SEd Tanous "provided with param imageUrl.");
617120fa86aSPrzemyslaw Czarnowski
618120fa86aSPrzemyslaw Czarnowski messages::actionParameterValueTypeError(
619e01d0c36SEd Tanous asyncResp->res, actionParams.transferProtocolType.value_or(""),
620120fa86aSPrzemyslaw Czarnowski "TransferProtocolType", "InsertMedia");
621120fa86aSPrzemyslaw Czarnowski
622120fa86aSPrzemyslaw Czarnowski return;
623120fa86aSPrzemyslaw Czarnowski }
624120fa86aSPrzemyslaw Czarnowski }
625120fa86aSPrzemyslaw Czarnowski
626120fa86aSPrzemyslaw Czarnowski // validation passed, add protocol to URI if needed
6277ead48e6SBoleslaw Ogonczyk Makowski if (!uriTransferProtocolType && paramTransferProtocolType)
628120fa86aSPrzemyslaw Czarnowski {
629120fa86aSPrzemyslaw Czarnowski actionParams.imageUrl = getUriWithTransferProtocol(
630120fa86aSPrzemyslaw Czarnowski *actionParams.imageUrl, *paramTransferProtocolType);
631120fa86aSPrzemyslaw Czarnowski }
632120fa86aSPrzemyslaw Czarnowski
633452bd8d8SJayaprakash Mutyala if (!actionParams.userName)
634452bd8d8SJayaprakash Mutyala {
635452bd8d8SJayaprakash Mutyala actionParams.userName = "";
636452bd8d8SJayaprakash Mutyala }
637452bd8d8SJayaprakash Mutyala
638452bd8d8SJayaprakash Mutyala if (!actionParams.password)
639452bd8d8SJayaprakash Mutyala {
640452bd8d8SJayaprakash Mutyala actionParams.password = "";
641452bd8d8SJayaprakash Mutyala }
642452bd8d8SJayaprakash Mutyala
643120fa86aSPrzemyslaw Czarnowski doMountVmLegacy(asyncResp, service, resName, *actionParams.imageUrl,
644e01d0c36SEd Tanous !(actionParams.writeProtected.value_or(false)),
645120fa86aSPrzemyslaw Czarnowski std::move(*actionParams.userName),
646120fa86aSPrzemyslaw Czarnowski std::move(*actionParams.password));
647120fa86aSPrzemyslaw Czarnowski }
648120fa86aSPrzemyslaw Czarnowski
649120fa86aSPrzemyslaw Czarnowski /**
650e13c2760SPrzemyslaw Czarnowski * @brief Function transceives data with dbus directly.
651e13c2760SPrzemyslaw Czarnowski *
652e13c2760SPrzemyslaw Czarnowski * All BMC state properties will be retrieved before sending reset request.
653e13c2760SPrzemyslaw Czarnowski */
doEjectAction(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & service,const std::string & name,bool legacy)65424e740a7SEd Tanous inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
655e13c2760SPrzemyslaw Czarnowski const std::string& service, const std::string& name,
656e13c2760SPrzemyslaw Czarnowski bool legacy)
657e13c2760SPrzemyslaw Czarnowski {
658e13c2760SPrzemyslaw Czarnowski // Legacy mount requires parameter with image
659e13c2760SPrzemyslaw Czarnowski if (legacy)
660e13c2760SPrzemyslaw Czarnowski {
661e13c2760SPrzemyslaw Czarnowski crow::connections::systemBus->async_method_call(
6625e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) {
663e13c2760SPrzemyslaw Czarnowski if (ec)
664e13c2760SPrzemyslaw Czarnowski {
66562598e31SEd Tanous BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
666e13c2760SPrzemyslaw Czarnowski
667e13c2760SPrzemyslaw Czarnowski messages::internalError(asyncResp->res);
668e13c2760SPrzemyslaw Czarnowski return;
669e13c2760SPrzemyslaw Czarnowski }
670e13c2760SPrzemyslaw Czarnowski },
671e13c2760SPrzemyslaw Czarnowski service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
672e13c2760SPrzemyslaw Czarnowski "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
673e13c2760SPrzemyslaw Czarnowski }
674e13c2760SPrzemyslaw Czarnowski else // proxy
675e13c2760SPrzemyslaw Czarnowski {
676e13c2760SPrzemyslaw Czarnowski crow::connections::systemBus->async_method_call(
6775e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) {
678e13c2760SPrzemyslaw Czarnowski if (ec)
679e13c2760SPrzemyslaw Czarnowski {
68062598e31SEd Tanous BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
681e13c2760SPrzemyslaw Czarnowski
682e13c2760SPrzemyslaw Czarnowski messages::internalError(asyncResp->res);
683e13c2760SPrzemyslaw Czarnowski return;
684e13c2760SPrzemyslaw Czarnowski }
685e13c2760SPrzemyslaw Czarnowski },
686e13c2760SPrzemyslaw Czarnowski service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
687e13c2760SPrzemyslaw Czarnowski "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
688e13c2760SPrzemyslaw Czarnowski }
689e13c2760SPrzemyslaw Czarnowski }
690e13c2760SPrzemyslaw Czarnowski
handleManagersVirtualMediaActionInsertPost(crow::App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & name,const std::string & resName)69196825bebSEd Tanous inline void handleManagersVirtualMediaActionInsertPost(
69296825bebSEd Tanous crow::App& app, const crow::Request& req,
69322db1728SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
69496825bebSEd Tanous const std::string& name, const std::string& resName)
69596825bebSEd Tanous {
6963ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
69745ca1b86SEd Tanous {
69845ca1b86SEd Tanous return;
69945ca1b86SEd Tanous }
70079fdf63eSPrzemyslaw Czarnowski
70179fdf63eSPrzemyslaw Czarnowski constexpr std::string_view action = "VirtualMedia.InsertMedia";
70222db1728SEd Tanous if (name != "bmc")
703107077deSPrzemyslaw Czarnowski {
70479fdf63eSPrzemyslaw Czarnowski messages::resourceNotFound(asyncResp->res, action, resName);
705107077deSPrzemyslaw Czarnowski
706107077deSPrzemyslaw Czarnowski return;
707107077deSPrzemyslaw Czarnowski }
70879fdf63eSPrzemyslaw Czarnowski InsertMediaActionParams actionParams;
70998be3e39SEd Tanous
710120fa86aSPrzemyslaw Czarnowski // Read obligatory parameters (url of image)
711afc474aeSMyung Bae if (!json_util::readJsonAction( //
712afc474aeSMyung Bae req, asyncResp->res, //
713afc474aeSMyung Bae "Image", actionParams.imageUrl, //
714afc474aeSMyung Bae "Inserted", actionParams.inserted, //
715afc474aeSMyung Bae "Password", actionParams.password, //
716afc474aeSMyung Bae "TransferMethod", actionParams.transferMethod, //
717afc474aeSMyung Bae "TransferProtocolType", actionParams.transferProtocolType, //
718afc474aeSMyung Bae "UserName", actionParams.userName, //
719afc474aeSMyung Bae "WriteProtected", actionParams.writeProtected //
720afc474aeSMyung Bae ))
72198be3e39SEd Tanous {
72298be3e39SEd Tanous return;
72398be3e39SEd Tanous }
724107077deSPrzemyslaw Czarnowski
7252b73119cSGeorge Liu dbus::utility::getDbusObject(
7262b73119cSGeorge Liu "/xyz/openbmc_project/VirtualMedia", {},
72779fdf63eSPrzemyslaw Czarnowski [asyncResp, action, actionParams,
7282b73119cSGeorge Liu resName](const boost::system::error_code& ec,
729002d39b4SEd Tanous const dbus::utility::MapperGetObject& getObjectType) mutable {
73022db1728SEd Tanous if (ec)
73122db1728SEd Tanous {
73262598e31SEd Tanous BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
73379fdf63eSPrzemyslaw Czarnowski messages::resourceNotFound(asyncResp->res, action, resName);
734107077deSPrzemyslaw Czarnowski
73522db1728SEd Tanous return;
73622db1728SEd Tanous }
73779fdf63eSPrzemyslaw Czarnowski
73822db1728SEd Tanous std::string service = getObjectType.begin()->first;
73962598e31SEd Tanous BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
74022db1728SEd Tanous
7415eb468daSGeorge Liu sdbusplus::message::object_path path(
7425eb468daSGeorge Liu "/xyz/openbmc_project/VirtualMedia");
7435eb468daSGeorge Liu dbus::utility::getManagedObjects(
7445eb468daSGeorge Liu service, path,
7455eb468daSGeorge Liu [service, resName, action, actionParams, asyncResp](
7465eb468daSGeorge Liu const boost::system::error_code& ec2,
7475eb468daSGeorge Liu const dbus::utility::ManagedObjectType& subtree) mutable {
7488a592810SEd Tanous if (ec2)
74922db1728SEd Tanous {
75079fdf63eSPrzemyslaw Czarnowski // Not possible in proxy mode
75162598e31SEd Tanous BMCWEB_LOG_DEBUG("InsertMedia not "
75262598e31SEd Tanous "allowed in proxy mode");
753bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, action,
754bd79bce8SPatrick Williams resName);
75522db1728SEd Tanous
75622db1728SEd Tanous return;
75722db1728SEd Tanous }
75822db1728SEd Tanous for (const auto& object : subtree)
75922db1728SEd Tanous {
760bd79bce8SPatrick Williams VmMode mode =
761bd79bce8SPatrick Williams parseObjectPathAndGetMode(object.first, resName);
7625880f0c5SBoleslaw Ogonczyk Makowski if (mode == VmMode::Legacy)
76322db1728SEd Tanous {
764bd79bce8SPatrick Williams validateParams(asyncResp, service, resName,
765bd79bce8SPatrick Williams actionParams);
76622db1728SEd Tanous
76722db1728SEd Tanous return;
76822db1728SEd Tanous }
76922db1728SEd Tanous }
77062598e31SEd Tanous BMCWEB_LOG_DEBUG("Parent item not found");
771bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "VirtualMedia",
772bd79bce8SPatrick Williams resName);
7735eb468daSGeorge Liu });
7742b73119cSGeorge Liu });
77596825bebSEd Tanous }
77622db1728SEd Tanous
handleManagersVirtualMediaActionEject(crow::App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & managerName,const std::string & resName)77796825bebSEd Tanous inline void handleManagersVirtualMediaActionEject(
77896825bebSEd Tanous crow::App& app, const crow::Request& req,
77922db1728SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
78096825bebSEd Tanous const std::string& managerName, const std::string& resName)
78196825bebSEd Tanous {
7823ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
78345ca1b86SEd Tanous {
78445ca1b86SEd Tanous return;
78545ca1b86SEd Tanous }
78679fdf63eSPrzemyslaw Czarnowski
78779fdf63eSPrzemyslaw Czarnowski constexpr std::string_view action = "VirtualMedia.EjectMedia";
78896825bebSEd Tanous if (managerName != "bmc")
789107077deSPrzemyslaw Czarnowski {
79079fdf63eSPrzemyslaw Czarnowski messages::resourceNotFound(asyncResp->res, action, resName);
79122db1728SEd Tanous
79222db1728SEd Tanous return;
79322db1728SEd Tanous }
79422db1728SEd Tanous
7952b73119cSGeorge Liu dbus::utility::getDbusObject(
7962b73119cSGeorge Liu "/xyz/openbmc_project/VirtualMedia", {},
79779fdf63eSPrzemyslaw Czarnowski [asyncResp, action,
7982b73119cSGeorge Liu resName](const boost::system::error_code& ec2,
799b9d36b47SEd Tanous const dbus::utility::MapperGetObject& getObjectType) {
8008a592810SEd Tanous if (ec2)
80122db1728SEd Tanous {
802bd79bce8SPatrick Williams BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}",
803bd79bce8SPatrick Williams ec2);
80422db1728SEd Tanous messages::internalError(asyncResp->res);
80522db1728SEd Tanous
80622db1728SEd Tanous return;
80722db1728SEd Tanous }
80822db1728SEd Tanous std::string service = getObjectType.begin()->first;
80962598e31SEd Tanous BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
81022db1728SEd Tanous
8115eb468daSGeorge Liu sdbusplus::message::object_path path(
8125eb468daSGeorge Liu "/xyz/openbmc_project/VirtualMedia");
8135eb468daSGeorge Liu dbus::utility::getManagedObjects(
8145eb468daSGeorge Liu service, path,
81579fdf63eSPrzemyslaw Czarnowski [resName, service, action,
81679fdf63eSPrzemyslaw Czarnowski asyncResp](const boost::system::error_code& ec,
81702cad96eSEd Tanous const dbus::utility::ManagedObjectType& subtree) {
81822db1728SEd Tanous if (ec)
81922db1728SEd Tanous {
82062598e31SEd Tanous BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
821bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, action,
822bd79bce8SPatrick Williams resName);
82322db1728SEd Tanous return;
82422db1728SEd Tanous }
82522db1728SEd Tanous
82622db1728SEd Tanous for (const auto& object : subtree)
82722db1728SEd Tanous {
828bd79bce8SPatrick Williams VmMode mode =
829bd79bce8SPatrick Williams parseObjectPathAndGetMode(object.first, resName);
830365a73f4SEd Tanous if (mode != VmMode::Invalid)
83122db1728SEd Tanous {
832365a73f4SEd Tanous doEjectAction(asyncResp, service, resName,
833365a73f4SEd Tanous mode == VmMode::Legacy);
8345880f0c5SBoleslaw Ogonczyk Makowski return;
83522db1728SEd Tanous }
83622db1728SEd Tanous }
83762598e31SEd Tanous BMCWEB_LOG_DEBUG("Parent item not found");
838bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "VirtualMedia",
839bd79bce8SPatrick Williams resName);
8405eb468daSGeorge Liu });
8412b73119cSGeorge Liu });
84296825bebSEd Tanous }
84396825bebSEd Tanous
handleManagersVirtualMediaCollectionGet(crow::App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & name)84496825bebSEd Tanous inline void handleManagersVirtualMediaCollectionGet(
84596825bebSEd Tanous crow::App& app, const crow::Request& req,
84622db1728SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
84796825bebSEd Tanous const std::string& name)
84896825bebSEd Tanous {
8493ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
85045ca1b86SEd Tanous {
85145ca1b86SEd Tanous return;
85245ca1b86SEd Tanous }
85322db1728SEd Tanous if (name != "bmc")
85422db1728SEd Tanous {
855002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
856107077deSPrzemyslaw Czarnowski
857107077deSPrzemyslaw Czarnowski return;
858107077deSPrzemyslaw Czarnowski }
859107077deSPrzemyslaw Czarnowski
8608d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] =
861107077deSPrzemyslaw Czarnowski "#VirtualMediaCollection.VirtualMediaCollection";
8628d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
863ef4c65b7SEd Tanous asyncResp->res.jsonValue["@odata.id"] =
864ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia", name);
865107077deSPrzemyslaw Czarnowski
8662b73119cSGeorge Liu dbus::utility::getDbusObject(
8672b73119cSGeorge Liu "/xyz/openbmc_project/VirtualMedia", {},
8682b73119cSGeorge Liu [asyncResp, name](const boost::system::error_code& ec,
869b9d36b47SEd Tanous const dbus::utility::MapperGetObject& getObjectType) {
870107077deSPrzemyslaw Czarnowski if (ec)
871107077deSPrzemyslaw Czarnowski {
87262598e31SEd Tanous BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
873107077deSPrzemyslaw Czarnowski messages::internalError(asyncResp->res);
874107077deSPrzemyslaw Czarnowski
875107077deSPrzemyslaw Czarnowski return;
876107077deSPrzemyslaw Czarnowski }
877107077deSPrzemyslaw Czarnowski std::string service = getObjectType.begin()->first;
87862598e31SEd Tanous BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
879107077deSPrzemyslaw Czarnowski
880107077deSPrzemyslaw Czarnowski getVmResourceList(asyncResp, service, name);
8812b73119cSGeorge Liu });
88296825bebSEd Tanous }
883107077deSPrzemyslaw Czarnowski
88496825bebSEd Tanous inline void
handleVirtualMediaGet(crow::App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & name,const std::string & resName)88596825bebSEd Tanous handleVirtualMediaGet(crow::App& app, const crow::Request& req,
88622db1728SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
88796825bebSEd Tanous const std::string& name, const std::string& resName)
88896825bebSEd Tanous {
8893ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
89045ca1b86SEd Tanous {
89145ca1b86SEd Tanous return;
89245ca1b86SEd Tanous }
893107077deSPrzemyslaw Czarnowski if (name != "bmc")
894107077deSPrzemyslaw Czarnowski {
895002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
896107077deSPrzemyslaw Czarnowski
897107077deSPrzemyslaw Czarnowski return;
898107077deSPrzemyslaw Czarnowski }
899107077deSPrzemyslaw Czarnowski
9002b73119cSGeorge Liu dbus::utility::getDbusObject(
9012b73119cSGeorge Liu "/xyz/openbmc_project/VirtualMedia", {},
902002d39b4SEd Tanous [asyncResp, name,
9032b73119cSGeorge Liu resName](const boost::system::error_code& ec,
904b9d36b47SEd Tanous const dbus::utility::MapperGetObject& getObjectType) {
905107077deSPrzemyslaw Czarnowski if (ec)
906107077deSPrzemyslaw Czarnowski {
90762598e31SEd Tanous BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
908107077deSPrzemyslaw Czarnowski messages::internalError(asyncResp->res);
909107077deSPrzemyslaw Czarnowski
910107077deSPrzemyslaw Czarnowski return;
911107077deSPrzemyslaw Czarnowski }
912107077deSPrzemyslaw Czarnowski std::string service = getObjectType.begin()->first;
91362598e31SEd Tanous BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
914107077deSPrzemyslaw Czarnowski
915107077deSPrzemyslaw Czarnowski getVmData(asyncResp, service, name, resName);
9162b73119cSGeorge Liu });
91796825bebSEd Tanous }
91896825bebSEd Tanous
requestNBDVirtualMediaRoutes(App & app)91996825bebSEd Tanous inline void requestNBDVirtualMediaRoutes(App& app)
92096825bebSEd Tanous {
92196825bebSEd Tanous BMCWEB_ROUTE(
92296825bebSEd Tanous app,
92396825bebSEd Tanous "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
92496825bebSEd Tanous .privileges(redfish::privileges::postVirtualMedia)
92596825bebSEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front(
92696825bebSEd Tanous handleManagersVirtualMediaActionInsertPost, std::ref(app)));
92796825bebSEd Tanous
92896825bebSEd Tanous BMCWEB_ROUTE(
92996825bebSEd Tanous app,
93096825bebSEd Tanous "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
93196825bebSEd Tanous .privileges(redfish::privileges::postVirtualMedia)
93296825bebSEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front(
93396825bebSEd Tanous handleManagersVirtualMediaActionEject, std::ref(app)));
93496825bebSEd Tanous
93596825bebSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
93696825bebSEd Tanous .privileges(redfish::privileges::getVirtualMediaCollection)
93796825bebSEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front(
93896825bebSEd Tanous handleManagersVirtualMediaCollectionGet, std::ref(app)));
93996825bebSEd Tanous
94096825bebSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
94196825bebSEd Tanous .privileges(redfish::privileges::getVirtualMedia)
94296825bebSEd Tanous .methods(boost::beast::http::verb::get)(
94396825bebSEd Tanous std::bind_front(handleVirtualMediaGet, std::ref(app)));
944107077deSPrzemyslaw Czarnowski }
945107077deSPrzemyslaw Czarnowski
946107077deSPrzemyslaw Czarnowski } // namespace redfish
947