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" 7*d7857201SEd Tanous #include "async_resp.hpp" 8*d7857201SEd Tanous #include "error_messages.hpp" 9*d7857201SEd Tanous #include "http_request.hpp" 103ccb3adbSEd Tanous #include "query.hpp" 1170304cb5SJason M. Bills #include "registries.hpp" 12*d7857201SEd Tanous #include "registries/privilege_registry.hpp" 13f7a26073SMyung Bae #include "registries_selector.hpp" 1470304cb5SJason M. Bills 15*d7857201SEd Tanous #include <boost/beast/http/verb.hpp> 16ef4c65b7SEd Tanous #include <boost/url/format.hpp> 17ef4c65b7SEd Tanous 18613dabeaSEd Tanous #include <array> 1956b81992SEd Tanous #include <format> 20*d7857201SEd Tanous #include <functional> 21*d7857201SEd Tanous #include <memory> 22*d7857201SEd Tanous #include <optional> 23*d7857201SEd Tanous #include <span> 24*d7857201SEd Tanous #include <utility> 25613dabeaSEd Tanous 2670304cb5SJason M. Bills namespace redfish 2770304cb5SJason M. Bills { 2870304cb5SJason M. Bills 29dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet( 3045ca1b86SEd Tanous crow::App& app, const crow::Request& req, 31104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3270304cb5SJason M. Bills { 333ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3445ca1b86SEd Tanous { 3545ca1b86SEd Tanous return; 3645ca1b86SEd Tanous } 377e860f15SJohn Edward Broadbent // Collections don't include the static data added by SubRoute 387e860f15SJohn Edward Broadbent // because it has a duplicate entry for members 3914c8aee2SEd Tanous 401476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 411476687dSEd Tanous "#MessageRegistryFileCollection.MessageRegistryFileCollection"; 421476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries"; 431476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection"; 441476687dSEd Tanous asyncResp->res.jsonValue["Description"] = 451476687dSEd Tanous "Collection of MessageRegistryFiles"; 46613dabeaSEd Tanous 47613dabeaSEd Tanous nlohmann::json& members = asyncResp->res.jsonValue["Members"]; 48fb546105SMyung Bae 49fb546105SMyung Bae static constexpr const auto registryFiles = std::to_array( 50fb546105SMyung Bae {"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry", 51fb546105SMyung Bae "HeartbeatEvent"}); 52fb546105SMyung Bae 53fb546105SMyung Bae for (const char* memberName : registryFiles) 54613dabeaSEd Tanous { 55613dabeaSEd Tanous nlohmann::json::object_t member; 56bd79bce8SPatrick Williams member["@odata.id"] = 57bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Registries/{}", memberName); 58613dabeaSEd Tanous members.emplace_back(std::move(member)); 59613dabeaSEd Tanous } 60fb546105SMyung Bae asyncResp->res.jsonValue["Members@odata.count"] = members.size(); 6170304cb5SJason M. Bills } 6270304cb5SJason M. Bills 63dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app) 6470304cb5SJason M. Bills { 65dff07827SJohn Edward Broadbent /** 66dff07827SJohn Edward Broadbent * Functions triggers appropriate requests on DBus 67dff07827SJohn Edward Broadbent */ 68dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/") 69dff07827SJohn Edward Broadbent .privileges(redfish::privileges::getMessageRegistryFileCollection) 7045ca1b86SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 7145ca1b86SEd Tanous handleMessageRegistryFileCollectionGet, std::ref(app))); 72dff07827SJohn Edward Broadbent } 73dff07827SJohn Edward Broadbent 74dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet( 7545ca1b86SEd Tanous crow::App& app, const crow::Request& req, 76104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 77dff07827SJohn Edward Broadbent const std::string& registry) 78dff07827SJohn Edward Broadbent { 793ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 8045ca1b86SEd Tanous { 8145ca1b86SEd Tanous return; 8245ca1b86SEd Tanous } 83e51c710eSJames Feist std::string dmtf = "DMTF "; 84f7a26073SMyung Bae std::optional<registries::HeaderAndUrl> headerAndUrl = 85f7a26073SMyung Bae registries::getRegistryHeaderAndUrlFromPrefix(registry); 86e51c710eSJames Feist 87f7a26073SMyung Bae if (!headerAndUrl) 88e51c710eSJames Feist { 89d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 907e860f15SJohn Edward Broadbent registry); 91e51c710eSJames Feist return; 92e51c710eSJames Feist } 93f7a26073SMyung Bae if (registry == "OpenBMC") 94f7a26073SMyung Bae { 95f7a26073SMyung Bae dmtf.clear(); 96f7a26073SMyung Bae } 97f7a26073SMyung Bae const registries::Header& header = headerAndUrl->header; 98f7a26073SMyung Bae const char* url = headerAndUrl->url; 99e51c710eSJames Feist 1001476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 101ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Registries/{}", registry); 1021476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 1031476687dSEd Tanous "#MessageRegistryFile.v1_1_0.MessageRegistryFile"; 1041476687dSEd Tanous asyncResp->res.jsonValue["Name"] = registry + " Message Registry File"; 105bd79bce8SPatrick Williams asyncResp->res.jsonValue["Description"] = 106bd79bce8SPatrick Williams dmtf + registry + " Message Registry File Location"; 107f7a26073SMyung Bae asyncResp->res.jsonValue["Id"] = header.registryPrefix; 10856b81992SEd Tanous asyncResp->res.jsonValue["Registry"] = 10956b81992SEd Tanous std::format("{}.{}.{}", header.registryPrefix, header.versionMajor, 11056b81992SEd Tanous header.versionMinor); 111613dabeaSEd Tanous nlohmann::json::array_t languages; 112f7a26073SMyung Bae languages.emplace_back(header.language); 113613dabeaSEd Tanous asyncResp->res.jsonValue["Languages@odata.count"] = languages.size(); 114613dabeaSEd Tanous asyncResp->res.jsonValue["Languages"] = std::move(languages); 115613dabeaSEd Tanous nlohmann::json::array_t locationMembers; 116613dabeaSEd Tanous nlohmann::json::object_t location; 117f7a26073SMyung Bae location["Language"] = header.language; 118613dabeaSEd Tanous location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry; 119e51c710eSJames Feist 120e51c710eSJames Feist if (url != nullptr) 121e51c710eSJames Feist { 122613dabeaSEd Tanous location["PublicationUri"] = url; 123e51c710eSJames Feist } 124613dabeaSEd Tanous locationMembers.emplace_back(std::move(location)); 125613dabeaSEd Tanous asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size(); 126613dabeaSEd Tanous asyncResp->res.jsonValue["Location"] = std::move(locationMembers); 12770304cb5SJason M. Bills } 12870304cb5SJason M. Bills 129dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app) 13070304cb5SJason M. Bills { 131dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/") 132ed398213SEd Tanous .privileges(redfish::privileges::getMessageRegistryFile) 13345ca1b86SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 13445ca1b86SEd Tanous handleMessageRoutesMessageRegistryFileGet, std::ref(app))); 135dff07827SJohn Edward Broadbent } 136dff07827SJohn Edward Broadbent 137dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet( 13845ca1b86SEd Tanous crow::App& app, const crow::Request& req, 139104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1406e8c18f0SJohn Edward Broadbent const std::string& registry, const std::string& registryMatch) 1417e860f15SJohn Edward Broadbent 142e51c710eSJames Feist { 1433ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 14445ca1b86SEd Tanous { 14545ca1b86SEd Tanous return; 14645ca1b86SEd Tanous } 147f7a26073SMyung Bae 148f7a26073SMyung Bae std::optional<registries::HeaderAndUrl> headerAndUrl = 149f7a26073SMyung Bae registries::getRegistryHeaderAndUrlFromPrefix(registry); 150f7a26073SMyung Bae if (!headerAndUrl) 151e51c710eSJames Feist { 152d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 1537e860f15SJohn Edward Broadbent registry); 154e51c710eSJames Feist return; 155e51c710eSJames Feist } 156e51c710eSJames Feist 157f7a26073SMyung Bae const registries::Header& header = headerAndUrl->header; 1586e8c18f0SJohn Edward Broadbent if (registry != registryMatch) 159e51c710eSJames Feist { 160f7a26073SMyung Bae messages::resourceNotFound(asyncResp->res, header.type, registryMatch); 161e51c710eSJames Feist return; 162e51c710eSJames Feist } 163e51c710eSJames Feist 164f7a26073SMyung Bae asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright; 165f7a26073SMyung Bae asyncResp->res.jsonValue["@odata.type"] = header.type; 16656b81992SEd Tanous asyncResp->res.jsonValue["Id"] = 16756b81992SEd Tanous std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor, 16856b81992SEd Tanous header.versionMinor, header.versionPatch); 169f7a26073SMyung Bae asyncResp->res.jsonValue["Name"] = header.name; 170f7a26073SMyung Bae asyncResp->res.jsonValue["Language"] = header.language; 171f7a26073SMyung Bae asyncResp->res.jsonValue["Description"] = header.description; 172f7a26073SMyung Bae asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix; 17356b81992SEd Tanous asyncResp->res.jsonValue["RegistryVersion"] = 17456b81992SEd Tanous std::format("{}.{}.{}", header.versionMajor, header.versionMinor, 17556b81992SEd Tanous header.versionPatch); 176f7a26073SMyung Bae asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity; 17770304cb5SJason M. Bills 178dff07827SJohn Edward Broadbent nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"]; 17970304cb5SJason M. Bills 18070304cb5SJason M. Bills // Go through the Message Registry and populate each Message 181f7a26073SMyung Bae const std::span<const registries::MessageEntry> registryEntries = 182f7a26073SMyung Bae registries::getRegistryFromPrefix(registry); 183f7a26073SMyung Bae 184f7a26073SMyung Bae for (const registries::MessageEntry& message : registryEntries) 18570304cb5SJason M. Bills { 186f7a26073SMyung Bae nlohmann::json& obj = messageObj[message.first]; 187f7a26073SMyung Bae obj["Description"] = message.second.description; 188f7a26073SMyung Bae obj["Message"] = message.second.message; 189f7a26073SMyung Bae obj["Severity"] = message.second.messageSeverity; 190f7a26073SMyung Bae obj["MessageSeverity"] = message.second.messageSeverity; 191f7a26073SMyung Bae obj["NumberOfArgs"] = message.second.numberOfArgs; 192f7a26073SMyung Bae obj["Resolution"] = message.second.resolution; 193f7a26073SMyung Bae if (message.second.numberOfArgs > 0) 19470304cb5SJason M. Bills { 19514c8aee2SEd Tanous nlohmann::json& messageParamArray = obj["ParamTypes"]; 196938f2568SEd Tanous messageParamArray = nlohmann::json::array(); 197f7a26073SMyung Bae for (const char* str : message.second.paramTypes) 19870304cb5SJason M. Bills { 19970304cb5SJason M. Bills if (str == nullptr) 20070304cb5SJason M. Bills { 20170304cb5SJason M. Bills break; 20270304cb5SJason M. Bills } 20370304cb5SJason M. Bills messageParamArray.push_back(str); 20470304cb5SJason M. Bills } 20570304cb5SJason M. Bills } 20670304cb5SJason M. Bills } 20770304cb5SJason M. Bills } 20870304cb5SJason M. Bills 209dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app) 210dff07827SJohn Edward Broadbent { 211dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/") 212dff07827SJohn Edward Broadbent .privileges(redfish::privileges::getMessageRegistryFile) 21345ca1b86SEd Tanous .methods(boost::beast::http::verb::get)( 21445ca1b86SEd Tanous std::bind_front(handleMessageRegistryGet, std::ref(app))); 215dff07827SJohn Edward Broadbent } 21670304cb5SJason M. Bills } // namespace redfish 217