140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2019 Intel Corporation 470304cb5SJason M. Bills #pragma once 570304cb5SJason M. Bills 63ccb3adbSEd Tanous #include "app.hpp" 7d7857201SEd Tanous #include "async_resp.hpp" 8d7857201SEd Tanous #include "error_messages.hpp" 9d7857201SEd Tanous #include "http_request.hpp" 103ccb3adbSEd Tanous #include "query.hpp" 1170304cb5SJason M. Bills #include "registries.hpp" 12d7857201SEd Tanous #include "registries/privilege_registry.hpp" 1370304cb5SJason M. Bills 14d7857201SEd Tanous #include <boost/beast/http/verb.hpp> 15ef4c65b7SEd Tanous #include <boost/url/format.hpp> 16ef4c65b7SEd Tanous 1756b81992SEd Tanous #include <format> 18d7857201SEd Tanous #include <functional> 19d7857201SEd Tanous #include <memory> 20d7857201SEd Tanous #include <optional> 21*4a102cd4SPatrick Williams #include <ranges> 22d7857201SEd Tanous #include <utility> 23613dabeaSEd Tanous 2470304cb5SJason M. Bills namespace redfish 2570304cb5SJason M. Bills { 2670304cb5SJason M. Bills 27dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet( 2845ca1b86SEd Tanous crow::App& app, const crow::Request& req, 29104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3070304cb5SJason M. Bills { 313ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3245ca1b86SEd Tanous { 3345ca1b86SEd Tanous return; 3445ca1b86SEd Tanous } 357e860f15SJohn Edward Broadbent // Collections don't include the static data added by SubRoute 367e860f15SJohn Edward Broadbent // because it has a duplicate entry for members 3714c8aee2SEd Tanous 381476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 391476687dSEd Tanous "#MessageRegistryFileCollection.MessageRegistryFileCollection"; 401476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries"; 411476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection"; 421476687dSEd Tanous asyncResp->res.jsonValue["Description"] = 431476687dSEd Tanous "Collection of MessageRegistryFiles"; 44613dabeaSEd Tanous 45613dabeaSEd Tanous nlohmann::json& members = asyncResp->res.jsonValue["Members"]; 46fb546105SMyung Bae 47*4a102cd4SPatrick Williams for (const auto& memberName : std::views::keys(registries::allRegistries())) 48613dabeaSEd Tanous { 49613dabeaSEd Tanous nlohmann::json::object_t member; 50bd79bce8SPatrick Williams member["@odata.id"] = 51bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Registries/{}", memberName); 52613dabeaSEd Tanous members.emplace_back(std::move(member)); 53613dabeaSEd Tanous } 54fb546105SMyung Bae asyncResp->res.jsonValue["Members@odata.count"] = members.size(); 5570304cb5SJason M. Bills } 5670304cb5SJason M. Bills 57dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app) 5870304cb5SJason M. Bills { 59dff07827SJohn Edward Broadbent /** 60dff07827SJohn Edward Broadbent * Functions triggers appropriate requests on DBus 61dff07827SJohn Edward Broadbent */ 62dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/") 63dff07827SJohn Edward Broadbent .privileges(redfish::privileges::getMessageRegistryFileCollection) 6445ca1b86SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 6545ca1b86SEd Tanous handleMessageRegistryFileCollectionGet, std::ref(app))); 66dff07827SJohn Edward Broadbent } 67dff07827SJohn Edward Broadbent 68dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet( 6945ca1b86SEd Tanous crow::App& app, const crow::Request& req, 70104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 71dff07827SJohn Edward Broadbent const std::string& registry) 72dff07827SJohn Edward Broadbent { 733ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 7445ca1b86SEd Tanous { 7545ca1b86SEd Tanous return; 7645ca1b86SEd Tanous } 77e51c710eSJames Feist std::string dmtf = "DMTF "; 78*4a102cd4SPatrick Williams std::optional<registries::RegistryEntryRef> registryEntry = 79*4a102cd4SPatrick Williams registries::getRegistryFromPrefix(registry); 80e51c710eSJames Feist 81*4a102cd4SPatrick Williams if (!registryEntry) 82e51c710eSJames Feist { 83d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 847e860f15SJohn Edward Broadbent registry); 85e51c710eSJames Feist return; 86e51c710eSJames Feist } 87f7a26073SMyung Bae if (registry == "OpenBMC") 88f7a26073SMyung Bae { 89f7a26073SMyung Bae dmtf.clear(); 90f7a26073SMyung Bae } 91*4a102cd4SPatrick Williams const registries::Header& header = registryEntry->get().header; 92*4a102cd4SPatrick Williams const char* url = registryEntry->get().url; 93e51c710eSJames Feist 941476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 95ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Registries/{}", registry); 961476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 971476687dSEd Tanous "#MessageRegistryFile.v1_1_0.MessageRegistryFile"; 981476687dSEd Tanous asyncResp->res.jsonValue["Name"] = registry + " Message Registry File"; 99bd79bce8SPatrick Williams asyncResp->res.jsonValue["Description"] = 100bd79bce8SPatrick Williams dmtf + registry + " Message Registry File Location"; 101f7a26073SMyung Bae asyncResp->res.jsonValue["Id"] = header.registryPrefix; 10256b81992SEd Tanous asyncResp->res.jsonValue["Registry"] = 10356b81992SEd Tanous std::format("{}.{}.{}", header.registryPrefix, header.versionMajor, 10456b81992SEd Tanous header.versionMinor); 105613dabeaSEd Tanous nlohmann::json::array_t languages; 106f7a26073SMyung Bae languages.emplace_back(header.language); 107613dabeaSEd Tanous asyncResp->res.jsonValue["Languages@odata.count"] = languages.size(); 108613dabeaSEd Tanous asyncResp->res.jsonValue["Languages"] = std::move(languages); 109613dabeaSEd Tanous nlohmann::json::array_t locationMembers; 110613dabeaSEd Tanous nlohmann::json::object_t location; 111f7a26073SMyung Bae location["Language"] = header.language; 112613dabeaSEd Tanous location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry; 113e51c710eSJames Feist 114e51c710eSJames Feist if (url != nullptr) 115e51c710eSJames Feist { 116613dabeaSEd Tanous location["PublicationUri"] = url; 117e51c710eSJames Feist } 118613dabeaSEd Tanous locationMembers.emplace_back(std::move(location)); 119613dabeaSEd Tanous asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size(); 120613dabeaSEd Tanous asyncResp->res.jsonValue["Location"] = std::move(locationMembers); 12170304cb5SJason M. Bills } 12270304cb5SJason M. Bills 123dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app) 12470304cb5SJason M. Bills { 125dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/") 126ed398213SEd Tanous .privileges(redfish::privileges::getMessageRegistryFile) 12745ca1b86SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 12845ca1b86SEd Tanous handleMessageRoutesMessageRegistryFileGet, std::ref(app))); 129dff07827SJohn Edward Broadbent } 130dff07827SJohn Edward Broadbent 131dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet( 13245ca1b86SEd Tanous crow::App& app, const crow::Request& req, 133104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1346e8c18f0SJohn Edward Broadbent const std::string& registry, const std::string& registryMatch) 1357e860f15SJohn Edward Broadbent 136e51c710eSJames Feist { 1373ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 13845ca1b86SEd Tanous { 13945ca1b86SEd Tanous return; 14045ca1b86SEd Tanous } 141f7a26073SMyung Bae 142*4a102cd4SPatrick Williams std::optional<registries::RegistryEntryRef> registryEntry = 143*4a102cd4SPatrick Williams registries::getRegistryFromPrefix(registry); 144*4a102cd4SPatrick Williams if (!registryEntry) 145e51c710eSJames Feist { 146d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 1477e860f15SJohn Edward Broadbent registry); 148e51c710eSJames Feist return; 149e51c710eSJames Feist } 150e51c710eSJames Feist 151*4a102cd4SPatrick Williams const registries::Header& header = registryEntry->get().header; 1526e8c18f0SJohn Edward Broadbent if (registry != registryMatch) 153e51c710eSJames Feist { 154f7a26073SMyung Bae messages::resourceNotFound(asyncResp->res, header.type, registryMatch); 155e51c710eSJames Feist return; 156e51c710eSJames Feist } 157e51c710eSJames Feist 158f7a26073SMyung Bae asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright; 159f7a26073SMyung Bae asyncResp->res.jsonValue["@odata.type"] = header.type; 16056b81992SEd Tanous asyncResp->res.jsonValue["Id"] = 16156b81992SEd Tanous std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor, 16256b81992SEd Tanous header.versionMinor, header.versionPatch); 163f7a26073SMyung Bae asyncResp->res.jsonValue["Name"] = header.name; 164f7a26073SMyung Bae asyncResp->res.jsonValue["Language"] = header.language; 165f7a26073SMyung Bae asyncResp->res.jsonValue["Description"] = header.description; 166f7a26073SMyung Bae asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix; 16756b81992SEd Tanous asyncResp->res.jsonValue["RegistryVersion"] = 16856b81992SEd Tanous std::format("{}.{}.{}", header.versionMajor, header.versionMinor, 16956b81992SEd Tanous header.versionPatch); 170f7a26073SMyung Bae asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity; 17170304cb5SJason M. Bills 172dff07827SJohn Edward Broadbent nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"]; 17370304cb5SJason M. Bills 17470304cb5SJason M. Bills // Go through the Message Registry and populate each Message 175*4a102cd4SPatrick Williams const registries::MessageEntries registryEntries = 176*4a102cd4SPatrick Williams registries::getRegistryMessagesFromPrefix(registry); 177f7a26073SMyung Bae 178f7a26073SMyung Bae for (const registries::MessageEntry& message : registryEntries) 17970304cb5SJason M. Bills { 180f7a26073SMyung Bae nlohmann::json& obj = messageObj[message.first]; 181f7a26073SMyung Bae obj["Description"] = message.second.description; 182f7a26073SMyung Bae obj["Message"] = message.second.message; 183f7a26073SMyung Bae obj["Severity"] = message.second.messageSeverity; 184f7a26073SMyung Bae obj["MessageSeverity"] = message.second.messageSeverity; 185f7a26073SMyung Bae obj["NumberOfArgs"] = message.second.numberOfArgs; 186f7a26073SMyung Bae obj["Resolution"] = message.second.resolution; 187f7a26073SMyung Bae if (message.second.numberOfArgs > 0) 18870304cb5SJason M. Bills { 18914c8aee2SEd Tanous nlohmann::json& messageParamArray = obj["ParamTypes"]; 190938f2568SEd Tanous messageParamArray = nlohmann::json::array(); 191f7a26073SMyung Bae for (const char* str : message.second.paramTypes) 19270304cb5SJason M. Bills { 19370304cb5SJason M. Bills if (str == nullptr) 19470304cb5SJason M. Bills { 19570304cb5SJason M. Bills break; 19670304cb5SJason M. Bills } 19770304cb5SJason M. Bills messageParamArray.push_back(str); 19870304cb5SJason M. Bills } 19970304cb5SJason M. Bills } 20070304cb5SJason M. Bills } 20170304cb5SJason M. Bills } 20270304cb5SJason M. Bills 203dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app) 204dff07827SJohn Edward Broadbent { 205dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/") 206dff07827SJohn Edward Broadbent .privileges(redfish::privileges::getMessageRegistryFile) 20745ca1b86SEd Tanous .methods(boost::beast::http::verb::get)( 20845ca1b86SEd Tanous std::bind_front(handleMessageRegistryGet, std::ref(app))); 209dff07827SJohn Edward Broadbent } 21070304cb5SJason M. Bills } // namespace redfish 211