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