blob: b6fc6d664381fca77bfd84839b878b003ce226c5 [file] [log] [blame]
Patrick Venture02e32372019-08-16 10:50:18 -07001#include "entity_map_json.hpp"
2
3#include <exception>
Patrick Venturec2b7fc12019-08-19 11:53:22 -07004#include <fstream>
Patrick Venture02e32372019-08-16 10:50:18 -07005#include <ipmid/types.hpp>
6#include <nlohmann/json.hpp>
7#include <string>
8#include <utility>
9
10namespace ipmi
11{
12namespace sensor
13{
14
Patrick Venturec2b7fc12019-08-19 11:53:22 -070015EntityInfoMap buildEntityMapFromFile()
16{
17 const char* entityMapJsonFilename =
18 "/usr/share/ipmi-providers/entity-map.json";
19 EntityInfoMap builtMap;
20
21 std::ifstream mapFile(entityMapJsonFilename);
22 if (!mapFile.is_open())
23 {
24 return builtMap;
25 }
26
27 auto data = nlohmann::json::parse(mapFile, nullptr, false);
28 if (data.is_discarded())
29 {
30 return builtMap;
31 }
32
33 return buildJsonEntityMap(data);
34}
35
Patrick Venture02e32372019-08-16 10:50:18 -070036EntityInfoMap buildJsonEntityMap(const nlohmann::json& data)
37{
38 EntityInfoMap builtMap;
39
40 if (data.type() != nlohmann::json::value_t::array)
41 {
42 return builtMap;
43 }
44
45 try
46 {
47 for (const auto& entry : data)
48 {
49 /* It's an array entry with the following fields: id,
50 * containerEntityId, containerEntityInstance, isList, isLinked,
51 * entities[4]
52 */
53 EntityInfo obj;
54 Id recordId = entry.at("id").get<Id>();
55 obj.containerEntityId =
56 entry.at("containerEntityId").get<uint8_t>();
57 obj.containerEntityInstance =
58 entry.at("containerEntityInstance").get<uint8_t>();
59 obj.isList = entry.at("isList").get<bool>();
60 obj.isLinked = entry.at("isLinked").get<bool>();
61
62 auto jsonEntities = entry.at("entities");
63
64 if (jsonEntities.type() != nlohmann::json::value_t::array)
65 {
66 throw std::runtime_error(
67 "Invalid type for entities entry, must be array");
68 }
69 if (jsonEntities.size() != obj.containedEntities.size())
70 {
71 throw std::runtime_error(
72 "Entities must be in pairs of " +
73 std::to_string(obj.containedEntities.size()));
74 }
75
76 for (std::size_t i = 0; i < obj.containedEntities.size(); i++)
77 {
78 obj.containedEntities[i] = std::make_pair(
79 jsonEntities[i].at("id").get<uint8_t>(),
80 jsonEntities[i].at("instance").get<uint8_t>());
81 }
82
83 builtMap.insert({recordId, obj});
84 }
85 }
86 catch (const std::exception& e)
87 {
88 /* If any entry is invalid, the entire file cannot be trusted. */
89 builtMap.clear();
90 }
91
92 return builtMap;
93}
94
95} // namespace sensor
96} // namespace ipmi