1 /* 2 // Copyright (c) 2019 Intel Corporation 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 */ 16 #pragma once 17 18 #include "registries.hpp" 19 #include "registries/base_message_registry.hpp" 20 #include "registries/openbmc_message_registry.hpp" 21 #include "registries/resource_event_message_registry.hpp" 22 #include "registries/task_event_message_registry.hpp" 23 24 #include <app.hpp> 25 #include <query.hpp> 26 #include <registries/privilege_registry.hpp> 27 28 #include <array> 29 30 namespace redfish 31 { 32 33 inline void handleMessageRegistryFileCollectionGet( 34 crow::App& app, const crow::Request& req, 35 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 36 { 37 if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 38 { 39 return; 40 } 41 // Collections don't include the static data added by SubRoute 42 // because it has a duplicate entry for members 43 44 asyncResp->res.jsonValue["@odata.type"] = 45 "#MessageRegistryFileCollection.MessageRegistryFileCollection"; 46 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries"; 47 asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection"; 48 asyncResp->res.jsonValue["Description"] = 49 "Collection of MessageRegistryFiles"; 50 asyncResp->res.jsonValue["Members@odata.count"] = 4; 51 52 nlohmann::json& members = asyncResp->res.jsonValue["Members"]; 53 for (const char* memberName : 54 std::to_array({"Base", "TaskEvent", "ResourceEvent", "OpenBMC"})) 55 { 56 nlohmann::json::object_t member; 57 member["@odata.id"] = crow::utility::urlFromPieces( 58 "redfish", "v1", "Registries", memberName); 59 members.emplace_back(std::move(member)); 60 } 61 } 62 63 inline void requestRoutesMessageRegistryFileCollection(App& app) 64 { 65 /** 66 * Functions triggers appropriate requests on DBus 67 */ 68 BMCWEB_ROUTE(app, "/redfish/v1/Registries/") 69 .privileges(redfish::privileges::getMessageRegistryFileCollection) 70 .methods(boost::beast::http::verb::get)(std::bind_front( 71 handleMessageRegistryFileCollectionGet, std::ref(app))); 72 } 73 74 inline void handleMessageRoutesMessageRegistryFileGet( 75 crow::App& app, const crow::Request& req, 76 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 77 const std::string& registry) 78 { 79 if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 80 { 81 return; 82 } 83 const registries::Header* header = nullptr; 84 std::string dmtf = "DMTF "; 85 const char* url = nullptr; 86 87 if (registry == "Base") 88 { 89 header = ®istries::base::header; 90 url = registries::base::url; 91 } 92 else if (registry == "TaskEvent") 93 { 94 header = ®istries::task_event::header; 95 url = registries::task_event::url; 96 } 97 else if (registry == "OpenBMC") 98 { 99 header = ®istries::openbmc::header; 100 dmtf.clear(); 101 } 102 else if (registry == "ResourceEvent") 103 { 104 header = ®istries::resource_event::header; 105 url = registries::resource_event::url; 106 } 107 else 108 { 109 messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 110 registry); 111 return; 112 } 113 114 asyncResp->res.jsonValue["@odata.id"] = 115 "/redfish/v1/Registries/" + registry; 116 asyncResp->res.jsonValue["@odata.type"] = 117 "#MessageRegistryFile.v1_1_0.MessageRegistryFile"; 118 asyncResp->res.jsonValue["Name"] = registry + " Message Registry File"; 119 asyncResp->res.jsonValue["Description"] = 120 dmtf + registry + " Message Registry File Location"; 121 asyncResp->res.jsonValue["Id"] = header->registryPrefix; 122 asyncResp->res.jsonValue["Registry"] = header->id; 123 nlohmann::json::array_t languages; 124 languages.push_back("en"); 125 asyncResp->res.jsonValue["Languages@odata.count"] = languages.size(); 126 asyncResp->res.jsonValue["Languages"] = std::move(languages); 127 nlohmann::json::array_t locationMembers; 128 nlohmann::json::object_t location; 129 location["Language"] = "en"; 130 location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry; 131 132 if (url != nullptr) 133 { 134 location["PublicationUri"] = url; 135 } 136 locationMembers.emplace_back(std::move(location)); 137 asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size(); 138 asyncResp->res.jsonValue["Location"] = std::move(locationMembers); 139 } 140 141 inline void requestRoutesMessageRegistryFile(App& app) 142 { 143 BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/") 144 .privileges(redfish::privileges::getMessageRegistryFile) 145 .methods(boost::beast::http::verb::get)(std::bind_front( 146 handleMessageRoutesMessageRegistryFileGet, std::ref(app))); 147 } 148 149 inline void handleMessageRegistryGet( 150 crow::App& app, const crow::Request& req, 151 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 152 const std::string& registry, const std::string& registryMatch) 153 154 { 155 if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 156 { 157 return; 158 } 159 const registries::Header* header = nullptr; 160 std::vector<const registries::MessageEntry*> registryEntries; 161 if (registry == "Base") 162 { 163 header = ®istries::base::header; 164 for (const registries::MessageEntry& entry : registries::base::registry) 165 { 166 registryEntries.emplace_back(&entry); 167 } 168 } 169 else if (registry == "TaskEvent") 170 { 171 header = ®istries::task_event::header; 172 for (const registries::MessageEntry& entry : 173 registries::task_event::registry) 174 { 175 registryEntries.emplace_back(&entry); 176 } 177 } 178 else if (registry == "OpenBMC") 179 { 180 header = ®istries::openbmc::header; 181 for (const registries::MessageEntry& entry : 182 registries::openbmc::registry) 183 { 184 registryEntries.emplace_back(&entry); 185 } 186 } 187 else if (registry == "ResourceEvent") 188 { 189 header = ®istries::resource_event::header; 190 for (const registries::MessageEntry& entry : 191 registries::resource_event::registry) 192 { 193 registryEntries.emplace_back(&entry); 194 } 195 } 196 else 197 { 198 messages::resourceNotFound(asyncResp->res, "MessageRegistryFile", 199 registry); 200 return; 201 } 202 203 if (registry != registryMatch) 204 { 205 messages::resourceNotFound(asyncResp->res, header->type, registryMatch); 206 return; 207 } 208 209 asyncResp->res.jsonValue["@Redfish.Copyright"] = header->copyright; 210 asyncResp->res.jsonValue["@odata.type"] = header->type; 211 asyncResp->res.jsonValue["Id"] = header->id; 212 asyncResp->res.jsonValue["Name"] = header->name; 213 asyncResp->res.jsonValue["Language"] = header->language; 214 asyncResp->res.jsonValue["Description"] = header->description; 215 asyncResp->res.jsonValue["RegistryPrefix"] = header->registryPrefix; 216 asyncResp->res.jsonValue["RegistryVersion"] = header->registryVersion; 217 asyncResp->res.jsonValue["OwningEntity"] = header->owningEntity; 218 219 nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"]; 220 221 // Go through the Message Registry and populate each Message 222 for (const registries::MessageEntry* message : registryEntries) 223 { 224 nlohmann::json& obj = messageObj[message->first]; 225 obj["Description"] = message->second.description; 226 obj["Message"] = message->second.message; 227 obj["Severity"] = message->second.messageSeverity; 228 obj["MessageSeverity"] = message->second.messageSeverity; 229 obj["NumberOfArgs"] = message->second.numberOfArgs; 230 obj["Resolution"] = message->second.resolution; 231 if (message->second.numberOfArgs > 0) 232 { 233 nlohmann::json& messageParamArray = obj["ParamTypes"]; 234 messageParamArray = nlohmann::json::array(); 235 for (const char* str : message->second.paramTypes) 236 { 237 if (str == nullptr) 238 { 239 break; 240 } 241 messageParamArray.push_back(str); 242 } 243 } 244 } 245 } 246 247 inline void requestRoutesMessageRegistry(App& app) 248 { 249 BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/") 250 .privileges(redfish::privileges::getMessageRegistryFile) 251 .methods(boost::beast::http::verb::get)( 252 std::bind_front(handleMessageRegistryGet, std::ref(app))); 253 } 254 } // namespace redfish 255