blob: 168c160fe9a300721496a6610028fc81f60dffb2 [file] [log] [blame]
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +00001#include "topology.hpp"
2
3#include <iostream>
4
5void Topology::addBoard(const std::string& path, const std::string& boardType,
Matt Spinler6eb60972023-08-14 16:36:20 -05006 const std::string& boardName,
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +00007 const nlohmann::json& exposesItem)
8{
9 auto findType = exposesItem.find("Type");
10 if (findType == exposesItem.end())
11 {
12 return;
13 }
Matt Spinler6eb60972023-08-14 16:36:20 -050014
15 boardNames.try_emplace(boardName, path);
16
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000017 PortType exposesType = findType->get<std::string>();
18
19 if (exposesType == "DownstreamPort")
20 {
21 auto findConnectsTo = exposesItem.find("ConnectsToType");
22 if (findConnectsTo == exposesItem.end())
23 {
24 std::cerr << "Board at path " << path
25 << " is missing ConnectsToType" << std::endl;
26 return;
27 }
28 PortType connectsTo = findConnectsTo->get<std::string>();
29
30 downstreamPorts[connectsTo].emplace_back(path);
31 boardTypes[path] = boardType;
Jeff Linb02752f2023-12-01 11:23:54 +080032 auto findPoweredBy = exposesItem.find("PowerPort");
33 if (findPoweredBy != exposesItem.end())
34 {
35 powerPaths.insert(path);
36 }
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000037 }
38 else if (exposesType.ends_with("Port"))
39 {
40 upstreamPorts[exposesType].emplace_back(path);
41 boardTypes[path] = boardType;
42 }
43}
44
Matt Spinler6eb60972023-08-14 16:36:20 -050045std::unordered_map<std::string, std::vector<Association>>
46 Topology::getAssocs(const std::map<Path, BoardName>& boards)
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000047{
48 std::unordered_map<std::string, std::vector<Association>> result;
49
50 // look at each upstream port type
51 for (const auto& upstreamPortPair : upstreamPorts)
52 {
53 auto downstreamMatch = downstreamPorts.find(upstreamPortPair.first);
54
55 if (downstreamMatch == downstreamPorts.end())
56 {
57 // no match
58 continue;
59 }
60
61 for (const Path& upstream : upstreamPortPair.second)
62 {
63 if (boardTypes[upstream] == "Chassis" ||
64 boardTypes[upstream] == "Board")
65 {
66 for (const Path& downstream : downstreamMatch->second)
67 {
Matt Spinler6eb60972023-08-14 16:36:20 -050068 // The downstream path must be one we care about.
69 if (boards.find(downstream) != boards.end())
70 {
71 result[downstream].emplace_back("contained_by",
72 "containing", upstream);
Jeff Linb02752f2023-12-01 11:23:54 +080073 if (powerPaths.find(downstream) != powerPaths.end())
74 {
75 result[upstream].emplace_back(
76 "powered_by", "powering", downstream);
77 }
Matt Spinler6eb60972023-08-14 16:36:20 -050078 }
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000079 }
80 }
81 }
82 }
83
84 return result;
85}
Matt Spinler6eb60972023-08-14 16:36:20 -050086
87void Topology::remove(const std::string& boardName)
88{
89 // Remove the board from boardNames, and then using the path
90 // found in boardNames remove it from upstreamPorts and
91 // downstreamPorts.
92 auto boardFind = boardNames.find(boardName);
93 if (boardFind == boardNames.end())
94 {
95 return;
96 }
97
98 std::string boardPath = boardFind->second;
99
100 boardNames.erase(boardFind);
101
102 for (auto it = upstreamPorts.begin(); it != upstreamPorts.end();)
103 {
Patrick Williamsb7077432024-08-16 15:22:21 -0400104 auto pathIt =
105 std::find(it->second.begin(), it->second.end(), boardPath);
Matt Spinler6eb60972023-08-14 16:36:20 -0500106 if (pathIt != it->second.end())
107 {
108 it->second.erase(pathIt);
109 }
110
111 if (it->second.empty())
112 {
113 it = upstreamPorts.erase(it);
114 }
115 else
116 {
117 ++it;
118 }
119 }
120
121 for (auto it = downstreamPorts.begin(); it != downstreamPorts.end();)
122 {
Patrick Williamsb7077432024-08-16 15:22:21 -0400123 auto pathIt =
124 std::find(it->second.begin(), it->second.end(), boardPath);
Matt Spinler6eb60972023-08-14 16:36:20 -0500125 if (pathIt != it->second.end())
126 {
127 it->second.erase(pathIt);
128 }
129
130 if (it->second.empty())
131 {
132 it = downstreamPorts.erase(it);
133 }
134 else
135 {
136 ++it;
137 }
138 }
139}