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