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