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 17c5ba4c27SEd Tanous 1856b81992SEd Tanous #include "bmcweb_config.h" 1956b81992SEd Tanous 2065e4f1f7SEd Tanous #include <nlohmann/json.hpp> 2165e4f1f7SEd Tanous 22d5c80ad9SNan Zhou #include <array> 2380f595e7SEd Tanous #include <charconv> 24d5c80ad9SNan Zhou #include <cstddef> 2556b81992SEd Tanous #include <format> 2680f595e7SEd Tanous #include <numeric> 27c5ba4c27SEd Tanous #include <span> 28c5ba4c27SEd Tanous #include <string> 29c5ba4c27SEd Tanous #include <string_view> 30d5c80ad9SNan Zhou #include <utility> 31d5c80ad9SNan Zhou 32fffb8c1fSEd Tanous namespace redfish::registries 3370304cb5SJason M. Bills { 34351d3063SJason M. Bills struct Header 35351d3063SJason M. Bills { 36351d3063SJason M. Bills const char* copyright; 37351d3063SJason M. Bills const char* type; 3856b81992SEd Tanous unsigned int versionMajor; 3956b81992SEd Tanous unsigned int versionMinor; 4056b81992SEd Tanous unsigned int versionPatch; 41351d3063SJason M. Bills const char* name; 42351d3063SJason M. Bills const char* language; 43351d3063SJason M. Bills const char* description; 44351d3063SJason M. Bills const char* registryPrefix; 45351d3063SJason M. Bills const char* owningEntity; 46351d3063SJason M. Bills }; 4770304cb5SJason M. Bills 4870304cb5SJason M. Bills struct Message 4970304cb5SJason M. Bills { 5070304cb5SJason M. Bills const char* description; 5170304cb5SJason M. Bills const char* message; 52e7808c93SGunnar Mills const char* messageSeverity; 53271584abSEd Tanous const size_t numberOfArgs; 5470304cb5SJason M. Bills std::array<const char*, 5> paramTypes; 5570304cb5SJason M. Bills const char* resolution; 5670304cb5SJason M. Bills }; 5770304cb5SJason M. Bills using MessageEntry = std::pair<const char*, const Message>; 58c5ba4c27SEd Tanous 59bd79bce8SPatrick Williams inline std::string fillMessageArgs( 60bd79bce8SPatrick Williams const std::span<const std::string_view> messageArgs, std::string_view msg) 61c5ba4c27SEd Tanous { 6280f595e7SEd Tanous std::string ret; 6380f595e7SEd Tanous size_t reserve = msg.size(); 6426ccae32SEd Tanous for (std::string_view arg : messageArgs) 65c5ba4c27SEd Tanous { 6680f595e7SEd Tanous reserve += arg.size(); 67c5ba4c27SEd Tanous } 6880f595e7SEd Tanous ret.reserve(reserve); 6980f595e7SEd Tanous 7080f595e7SEd Tanous for (size_t stringIndex = msg.find('%'); stringIndex != std::string::npos; 7180f595e7SEd Tanous stringIndex = msg.find('%')) 7280f595e7SEd Tanous { 7380f595e7SEd Tanous ret += msg.substr(0, stringIndex); 7480f595e7SEd Tanous msg.remove_prefix(stringIndex + 1); 7580f595e7SEd Tanous size_t number = 0; 76*7da633f0SEd Tanous auto it = std::from_chars(&*msg.begin(), &*msg.end(), number); 7780f595e7SEd Tanous if (it.ec != std::errc()) 7880f595e7SEd Tanous { 7980f595e7SEd Tanous return ""; 80c5ba4c27SEd Tanous } 8180f595e7SEd Tanous msg.remove_prefix(1); 8280f595e7SEd Tanous // Redfish message args are 1 indexed. 8380f595e7SEd Tanous number--; 8480f595e7SEd Tanous if (number >= messageArgs.size()) 8580f595e7SEd Tanous { 8680f595e7SEd Tanous return ""; 8780f595e7SEd Tanous } 8880f595e7SEd Tanous ret += messageArgs[number]; 8980f595e7SEd Tanous } 9080f595e7SEd Tanous ret += msg; 9180f595e7SEd Tanous return ret; 92c5ba4c27SEd Tanous } 93c5ba4c27SEd Tanous 94bd79bce8SPatrick Williams inline nlohmann::json::object_t getLogFromRegistry( 95bd79bce8SPatrick Williams const Header& header, std::span<const MessageEntry> registry, size_t index, 9665e4f1f7SEd Tanous std::span<const std::string_view> args) 9765e4f1f7SEd Tanous { 9865e4f1f7SEd Tanous const redfish::registries::MessageEntry& entry = registry[index]; 9965e4f1f7SEd Tanous // Intentionally make a copy of the string, so we can append in the 10065e4f1f7SEd Tanous // parameters. 1012e30bc2dSKrzysztof Grobelny std::string msg = 1022e30bc2dSKrzysztof Grobelny redfish::registries::fillMessageArgs(args, entry.second.message); 10365e4f1f7SEd Tanous nlohmann::json jArgs = nlohmann::json::array(); 10426ccae32SEd Tanous for (std::string_view arg : args) 10565e4f1f7SEd Tanous { 10665e4f1f7SEd Tanous jArgs.push_back(arg); 10765e4f1f7SEd Tanous } 10856b81992SEd Tanous std::string msgId; 10956b81992SEd Tanous if (BMCWEB_REDFISH_USE_3_DIGIT_MESSAGEID) 11056b81992SEd Tanous { 11156b81992SEd Tanous msgId = std::format("{}.{}.{}.{}.{}", header.registryPrefix, 11256b81992SEd Tanous header.versionMajor, header.versionMinor, 11356b81992SEd Tanous header.versionPatch, entry.first); 11456b81992SEd Tanous } 11556b81992SEd Tanous else 11656b81992SEd Tanous { 11756b81992SEd Tanous msgId = 11856b81992SEd Tanous std::format("{}.{}.{}.{}", header.registryPrefix, 11956b81992SEd Tanous header.versionMajor, header.versionMinor, entry.first); 12056b81992SEd Tanous } 12165e4f1f7SEd Tanous nlohmann::json::object_t response; 12265e4f1f7SEd Tanous response["@odata.type"] = "#Message.v1_1_1.Message"; 12365e4f1f7SEd Tanous response["MessageId"] = std::move(msgId); 12465e4f1f7SEd Tanous response["Message"] = std::move(msg); 12565e4f1f7SEd Tanous response["MessageArgs"] = std::move(jArgs); 12665e4f1f7SEd Tanous response["MessageSeverity"] = entry.second.messageSeverity; 12765e4f1f7SEd Tanous response["Resolution"] = entry.second.resolution; 12865e4f1f7SEd Tanous return response; 12965e4f1f7SEd Tanous } 13065e4f1f7SEd Tanous 131d1d411f9SSui Chen const Message* getMessage(std::string_view messageID); 132d1d411f9SSui Chen 133d1d411f9SSui Chen const Message* getMessageFromRegistry(const std::string& messageKey, 134d1d411f9SSui Chen std::span<const MessageEntry> registry); 135d1d411f9SSui Chen 136fffb8c1fSEd Tanous } // namespace redfish::registries 137