170304cb5SJason M. Bills /* 26be832e2SEd Tanous Copyright (c) 2019 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. 1570304cb5SJason M. Bills */ 1670304cb5SJason M. Bills #pragma once 1770304cb5SJason M. Bills 183ccb3adbSEd Tanous #include "app.hpp" 193ccb3adbSEd Tanous #include "query.hpp" 2070304cb5SJason M. Bills #include "registries.hpp" 21f7a26073SMyung Bae #include "registries_selector.hpp" 2270304cb5SJason M. Bills 23ef4c65b7SEd Tanous #include <boost/url/format.hpp> 24ef4c65b7SEd Tanous 25613dabeaSEd Tanous #include <array> 26*56b81992SEd Tanous #include <format> 27613dabeaSEd Tanous 2870304cb5SJason M. Bills namespace redfish 2970304cb5SJason M. Bills { 3070304cb5SJason M. Bills 31dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet( 3245ca1b86SEd Tanous crow::App& app, const crow::Request& req, 33104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3470304cb5SJason M. Bills { 353ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3645ca1b86SEd Tanous { 3745ca1b86SEd Tanous return; 3845ca1b86SEd Tanous } 397e860f15SJohn Edward Broadbent // Collections don't include the static data added by SubRoute 407e860f15SJohn Edward Broadbent // because it has a duplicate entry for members 4114c8aee2SEd Tanous 421476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 431476687dSEd Tanous "#MessageRegistryFileCollection.MessageRegistryFileCollection"; 441476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries"; 451476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection"; 461476687dSEd Tanous asyncResp->res.jsonValue["Description"] = 471476687dSEd Tanous "Collection of MessageRegistryFiles"; 48613dabeaSEd Tanous 49613dabeaSEd Tanous nlohmann::json& members = asyncResp->res.jsonValue["Members"]; 50fb546105SMyung Bae 51fb546105SMyung Bae static constexpr const auto registryFiles = std::to_array( 52fb546105SMyung Bae {"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry", 53fb546105SMyung Bae "HeartbeatEvent"}); 54fb546105SMyung Bae 55fb546105SMyung Bae for (const char* memberName : registryFiles) 56613dabeaSEd Tanous { 57613dabeaSEd Tanous nlohmann::json::object_t member; 58bd79bce8SPatrick Williams member["@odata.id"] = 59bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Registries/{}", memberName); 60613dabeaSEd Tanous members.emplace_back(std::move(member)); 61613dabeaSEd Tanous } 62fb546105SMyung Bae asyncResp->res.jsonValue["Members@odata.count"] = members.size(); 6370304cb5SJason M. Bills } 6470304cb5SJason M. Bills 65dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app) 6670304cb5SJason M. Bills { 67dff07827SJohn Edward Broadbent /** 68dff07827SJohn Edward Broadbent * Functions triggers appropriate requests on DBus 69dff07827SJohn Edward Broadbent */ 70dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/") 71dff07827SJohn Edward Broadbent .privileges(redfish::privileges::getMessageRegistryFileCollection) 7245ca1b86SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 7345ca1b86SEd Tanous handleMessageRegistryFileCollectionGet, std::ref(app))); 74dff07827SJohn Edward Broadbent } 75dff07827SJohn Edward Broadbent 76dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet( 7745ca1b86SEd Tanous crow::App& app, const crow::Request& req, 78104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 79dff07827SJohn Edward Broadbent const std::string& registry) 80dff07827SJohn Edward Broadbent { 813ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 8245ca1b86SEd Tanous { 8345ca1b86SEd Tanous return; 8445ca1b86SEd Tanous } 85e51c710eSJames Feist std::string dmtf = "DMTF "; 86f7a26073SMyung Bae std::optional<registries::HeaderAndUrl> headerAndUrl = 87f7a26073SMyung Bae registries::getRegistryHeaderAndUrlFromPrefix(registry); 88e51c710eSJames Feist 89f7a26073SMyung Bae if (!headerAndUrl) 90e51c710eSJames Feist { 91d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 927e860f15SJohn Edward Broadbent registry); 93e51c710eSJames Feist return; 94e51c710eSJames Feist } 95f7a26073SMyung Bae if (registry == "OpenBMC") 96f7a26073SMyung Bae { 97f7a26073SMyung Bae dmtf.clear(); 98f7a26073SMyung Bae } 99f7a26073SMyung Bae const registries::Header& header = headerAndUrl->header; 100f7a26073SMyung Bae const char* url = headerAndUrl->url; 101e51c710eSJames Feist 1021476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 103ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Registries/{}", registry); 1041476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 1051476687dSEd Tanous "#MessageRegistryFile.v1_1_0.MessageRegistryFile"; 1061476687dSEd Tanous asyncResp->res.jsonValue["Name"] = registry + " Message Registry File"; 107bd79bce8SPatrick Williams asyncResp->res.jsonValue["Description"] = 108bd79bce8SPatrick Williams dmtf + registry + " Message Registry File Location"; 109f7a26073SMyung Bae asyncResp->res.jsonValue["Id"] = header.registryPrefix; 110*56b81992SEd Tanous asyncResp->res.jsonValue["Registry"] = 111*56b81992SEd Tanous std::format("{}.{}.{}", header.registryPrefix, header.versionMajor, 112*56b81992SEd Tanous header.versionMinor); 113613dabeaSEd Tanous nlohmann::json::array_t languages; 114f7a26073SMyung Bae languages.emplace_back(header.language); 115613dabeaSEd Tanous asyncResp->res.jsonValue["Languages@odata.count"] = languages.size(); 116613dabeaSEd Tanous asyncResp->res.jsonValue["Languages"] = std::move(languages); 117613dabeaSEd Tanous nlohmann::json::array_t locationMembers; 118613dabeaSEd Tanous nlohmann::json::object_t location; 119f7a26073SMyung Bae location["Language"] = header.language; 120613dabeaSEd Tanous location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry; 121e51c710eSJames Feist 122e51c710eSJames Feist if (url != nullptr) 123e51c710eSJames Feist { 124613dabeaSEd Tanous location["PublicationUri"] = url; 125e51c710eSJames Feist } 126613dabeaSEd Tanous locationMembers.emplace_back(std::move(location)); 127613dabeaSEd Tanous asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size(); 128613dabeaSEd Tanous asyncResp->res.jsonValue["Location"] = std::move(locationMembers); 12970304cb5SJason M. Bills } 13070304cb5SJason M. Bills 131dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app) 13270304cb5SJason M. Bills { 133dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/") 134ed398213SEd Tanous .privileges(redfish::privileges::getMessageRegistryFile) 13545ca1b86SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 13645ca1b86SEd Tanous handleMessageRoutesMessageRegistryFileGet, std::ref(app))); 137dff07827SJohn Edward Broadbent } 138dff07827SJohn Edward Broadbent 139dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet( 14045ca1b86SEd Tanous crow::App& app, const crow::Request& req, 141104f09c9SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1426e8c18f0SJohn Edward Broadbent const std::string& registry, const std::string& registryMatch) 1437e860f15SJohn Edward Broadbent 144e51c710eSJames Feist { 1453ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 14645ca1b86SEd Tanous { 14745ca1b86SEd Tanous return; 14845ca1b86SEd Tanous } 149f7a26073SMyung Bae 150f7a26073SMyung Bae std::optional<registries::HeaderAndUrl> headerAndUrl = 151f7a26073SMyung Bae registries::getRegistryHeaderAndUrlFromPrefix(registry); 152f7a26073SMyung Bae if (!headerAndUrl) 153e51c710eSJames Feist { 154d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 1557e860f15SJohn Edward Broadbent registry); 156e51c710eSJames Feist return; 157e51c710eSJames Feist } 158e51c710eSJames Feist 159f7a26073SMyung Bae const registries::Header& header = headerAndUrl->header; 1606e8c18f0SJohn Edward Broadbent if (registry != registryMatch) 161e51c710eSJames Feist { 162f7a26073SMyung Bae messages::resourceNotFound(asyncResp->res, header.type, registryMatch); 163e51c710eSJames Feist return; 164e51c710eSJames Feist } 165e51c710eSJames Feist 166f7a26073SMyung Bae asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright; 167f7a26073SMyung Bae asyncResp->res.jsonValue["@odata.type"] = header.type; 168*56b81992SEd Tanous asyncResp->res.jsonValue["Id"] = 169*56b81992SEd Tanous std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor, 170*56b81992SEd Tanous header.versionMinor, header.versionPatch); 171f7a26073SMyung Bae asyncResp->res.jsonValue["Name"] = header.name; 172f7a26073SMyung Bae asyncResp->res.jsonValue["Language"] = header.language; 173f7a26073SMyung Bae asyncResp->res.jsonValue["Description"] = header.description; 174f7a26073SMyung Bae asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix; 175*56b81992SEd Tanous asyncResp->res.jsonValue["RegistryVersion"] = 176*56b81992SEd Tanous std::format("{}.{}.{}", header.versionMajor, header.versionMinor, 177*56b81992SEd Tanous header.versionPatch); 178f7a26073SMyung Bae asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity; 17970304cb5SJason M. Bills 180dff07827SJohn Edward Broadbent nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"]; 18170304cb5SJason M. Bills 18270304cb5SJason M. Bills // Go through the Message Registry and populate each Message 183f7a26073SMyung Bae const std::span<const registries::MessageEntry> registryEntries = 184f7a26073SMyung Bae registries::getRegistryFromPrefix(registry); 185f7a26073SMyung Bae 186f7a26073SMyung Bae for (const registries::MessageEntry& message : registryEntries) 18770304cb5SJason M. Bills { 188f7a26073SMyung Bae nlohmann::json& obj = messageObj[message.first]; 189f7a26073SMyung Bae obj["Description"] = message.second.description; 190f7a26073SMyung Bae obj["Message"] = message.second.message; 191f7a26073SMyung Bae obj["Severity"] = message.second.messageSeverity; 192f7a26073SMyung Bae obj["MessageSeverity"] = message.second.messageSeverity; 193f7a26073SMyung Bae obj["NumberOfArgs"] = message.second.numberOfArgs; 194f7a26073SMyung Bae obj["Resolution"] = message.second.resolution; 195f7a26073SMyung Bae if (message.second.numberOfArgs > 0) 19670304cb5SJason M. Bills { 19714c8aee2SEd Tanous nlohmann::json& messageParamArray = obj["ParamTypes"]; 198938f2568SEd Tanous messageParamArray = nlohmann::json::array(); 199f7a26073SMyung Bae for (const char* str : message.second.paramTypes) 20070304cb5SJason M. Bills { 20170304cb5SJason M. Bills if (str == nullptr) 20270304cb5SJason M. Bills { 20370304cb5SJason M. Bills break; 20470304cb5SJason M. Bills } 20570304cb5SJason M. Bills messageParamArray.push_back(str); 20670304cb5SJason M. Bills } 20770304cb5SJason M. Bills } 20870304cb5SJason M. Bills } 20970304cb5SJason M. Bills } 21070304cb5SJason M. Bills 211dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app) 212dff07827SJohn Edward Broadbent { 213dff07827SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/") 214dff07827SJohn Edward Broadbent .privileges(redfish::privileges::getMessageRegistryFile) 21545ca1b86SEd Tanous .methods(boost::beast::http::verb::get)( 21645ca1b86SEd Tanous std::bind_front(handleMessageRegistryGet, std::ref(app))); 217dff07827SJohn Edward Broadbent } 21870304cb5SJason M. Bills } // namespace redfish 219