1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "config.h"
15 
16 #include "bifurcation.hpp"
17 
18 #include <nlohmann/json.hpp>
19 #include <stdplus/print.hpp>
20 
21 #include <charconv>
22 #include <filesystem>
23 #include <fstream>
24 #include <optional>
25 #include <string_view>
26 #include <vector>
27 
28 namespace google
29 {
30 namespace ipmi
31 {
32 
BifurcationStatic()33 BifurcationStatic::BifurcationStatic() :
34     BifurcationStatic(STATIC_BIFURCATION_CONFIG)
35 {}
36 
BifurcationStatic(std::string_view bifurcationFile)37 BifurcationStatic::BifurcationStatic(std::string_view bifurcationFile) :
38     bifurcationFile(bifurcationFile)
39 {}
40 
41 std::optional<std::vector<uint8_t>>
getBifurcation(uint8_t index)42     BifurcationStatic::getBifurcation(uint8_t index) noexcept
43 {
44     // Example valid data:
45     // {
46     //     "1": [8,8],
47     //     "2": [4, 4, 12]
48     // }
49     std::ifstream jsonFile(bifurcationFile.c_str());
50     if (!jsonFile.is_open())
51     {
52         stdplus::print(stderr, "Unable to open file {} for bifurcation.\n",
53                        bifurcationFile.data());
54         return std::nullopt;
55     }
56 
57     nlohmann::json jsonData;
58     try
59     {
60         jsonData = nlohmann::json::parse(jsonFile, nullptr, false);
61     }
62     catch (const nlohmann::json::parse_error& ex)
63     {
64         stdplus::print(
65             stderr,
66             "Failed to parse the static config. Parse error at byte {}\n",
67             ex.byte);
68         return std::nullopt;
69     }
70 
71     std::vector<uint8_t> vec;
72     try
73     {
74         std::string key = std::to_string(index);
75         auto value = jsonData[key];
76         value.get_to(vec);
77     }
78     catch (const std::exception& e)
79     {
80         stdplus::print(stderr,
81                        "Failed to convert bifurcation value to vec[uin8_t]\n");
82         return std::nullopt;
83     }
84 
85     return vec;
86 }
87 
88 } // namespace ipmi
89 } // namespace google
90