1f2f5b7acSBenjamin Fair #include "topology.hpp"
2f2f5b7acSBenjamin Fair
3f2f5b7acSBenjamin Fair #include <iostream>
4f2f5b7acSBenjamin Fair
addBoard(const std::string & path,const std::string & boardType,const std::string & boardName,const nlohmann::json & exposesItem)5f2f5b7acSBenjamin Fair void Topology::addBoard(const std::string& path, const std::string& boardType,
66eb60972SMatt Spinler const std::string& boardName,
7f2f5b7acSBenjamin Fair const nlohmann::json& exposesItem)
8f2f5b7acSBenjamin Fair {
9f2f5b7acSBenjamin Fair auto findType = exposesItem.find("Type");
10f2f5b7acSBenjamin Fair if (findType == exposesItem.end())
11f2f5b7acSBenjamin Fair {
12f2f5b7acSBenjamin Fair return;
13f2f5b7acSBenjamin Fair }
146eb60972SMatt Spinler
156eb60972SMatt Spinler boardNames.try_emplace(boardName, path);
166eb60972SMatt Spinler
17f2f5b7acSBenjamin Fair PortType exposesType = findType->get<std::string>();
18f2f5b7acSBenjamin Fair
19f2f5b7acSBenjamin Fair if (exposesType == "DownstreamPort")
20f2f5b7acSBenjamin Fair {
21f2f5b7acSBenjamin Fair auto findConnectsTo = exposesItem.find("ConnectsToType");
22f2f5b7acSBenjamin Fair if (findConnectsTo == exposesItem.end())
23f2f5b7acSBenjamin Fair {
24f2f5b7acSBenjamin Fair std::cerr << "Board at path " << path
25f2f5b7acSBenjamin Fair << " is missing ConnectsToType" << std::endl;
26f2f5b7acSBenjamin Fair return;
27f2f5b7acSBenjamin Fair }
28f2f5b7acSBenjamin Fair PortType connectsTo = findConnectsTo->get<std::string>();
29f2f5b7acSBenjamin Fair
30f2f5b7acSBenjamin Fair downstreamPorts[connectsTo].emplace_back(path);
31f2f5b7acSBenjamin Fair boardTypes[path] = boardType;
32b02752f7SJeff Lin auto findPoweredBy = exposesItem.find("PowerPort");
33b02752f7SJeff Lin if (findPoweredBy != exposesItem.end())
34b02752f7SJeff Lin {
35b02752f7SJeff Lin powerPaths.insert(path);
36b02752f7SJeff Lin }
37f2f5b7acSBenjamin Fair }
38f2f5b7acSBenjamin Fair else if (exposesType.ends_with("Port"))
39f2f5b7acSBenjamin Fair {
40f2f5b7acSBenjamin Fair upstreamPorts[exposesType].emplace_back(path);
41f2f5b7acSBenjamin Fair boardTypes[path] = boardType;
42f2f5b7acSBenjamin Fair }
43f2f5b7acSBenjamin Fair }
44f2f5b7acSBenjamin Fair
getAssocs(const std::map<Path,BoardName> & boards)45*5a80703cSPatrick Williams std::unordered_map<std::string, std::vector<Association>> Topology::getAssocs(
46*5a80703cSPatrick Williams const std::map<Path, BoardName>& boards)
47f2f5b7acSBenjamin Fair {
48f2f5b7acSBenjamin Fair std::unordered_map<std::string, std::vector<Association>> result;
49f2f5b7acSBenjamin Fair
50f2f5b7acSBenjamin Fair // look at each upstream port type
51f2f5b7acSBenjamin Fair for (const auto& upstreamPortPair : upstreamPorts)
52f2f5b7acSBenjamin Fair {
53f2f5b7acSBenjamin Fair auto downstreamMatch = downstreamPorts.find(upstreamPortPair.first);
54f2f5b7acSBenjamin Fair
55f2f5b7acSBenjamin Fair if (downstreamMatch == downstreamPorts.end())
56f2f5b7acSBenjamin Fair {
57f2f5b7acSBenjamin Fair // no match
58f2f5b7acSBenjamin Fair continue;
59f2f5b7acSBenjamin Fair }
60f2f5b7acSBenjamin Fair
61f2f5b7acSBenjamin Fair for (const Path& upstream : upstreamPortPair.second)
62f2f5b7acSBenjamin Fair {
63f2f5b7acSBenjamin Fair if (boardTypes[upstream] == "Chassis" ||
64f2f5b7acSBenjamin Fair boardTypes[upstream] == "Board")
65f2f5b7acSBenjamin Fair {
66f2f5b7acSBenjamin Fair for (const Path& downstream : downstreamMatch->second)
67f2f5b7acSBenjamin Fair {
686eb60972SMatt Spinler // The downstream path must be one we care about.
696eb60972SMatt Spinler if (boards.find(downstream) != boards.end())
706eb60972SMatt Spinler {
71f2f5b7acSBenjamin Fair result[downstream].emplace_back("contained_by",
72f2f5b7acSBenjamin Fair "containing", upstream);
73b02752f7SJeff Lin if (powerPaths.find(downstream) != powerPaths.end())
74b02752f7SJeff Lin {
75b02752f7SJeff Lin result[upstream].emplace_back(
76b02752f7SJeff Lin "powered_by", "powering", downstream);
77b02752f7SJeff Lin }
78f2f5b7acSBenjamin Fair }
79f2f5b7acSBenjamin Fair }
80f2f5b7acSBenjamin Fair }
81f2f5b7acSBenjamin Fair }
826eb60972SMatt Spinler }
83f2f5b7acSBenjamin Fair
84f2f5b7acSBenjamin Fair return result;
85f2f5b7acSBenjamin Fair }
866eb60972SMatt Spinler
remove(const std::string & boardName)876eb60972SMatt Spinler void Topology::remove(const std::string& boardName)
886eb60972SMatt Spinler {
896eb60972SMatt Spinler // Remove the board from boardNames, and then using the path
906eb60972SMatt Spinler // found in boardNames remove it from upstreamPorts and
916eb60972SMatt Spinler // downstreamPorts.
926eb60972SMatt Spinler auto boardFind = boardNames.find(boardName);
936eb60972SMatt Spinler if (boardFind == boardNames.end())
946eb60972SMatt Spinler {
956eb60972SMatt Spinler return;
966eb60972SMatt Spinler }
976eb60972SMatt Spinler
986eb60972SMatt Spinler std::string boardPath = boardFind->second;
996eb60972SMatt Spinler
1006eb60972SMatt Spinler boardNames.erase(boardFind);
1016eb60972SMatt Spinler
1026eb60972SMatt Spinler for (auto it = upstreamPorts.begin(); it != upstreamPorts.end();)
1036eb60972SMatt Spinler {
104b7077437SPatrick Williams auto pathIt =
105b7077437SPatrick Williams std::find(it->second.begin(), it->second.end(), boardPath);
1066eb60972SMatt Spinler if (pathIt != it->second.end())
1076eb60972SMatt Spinler {
1086eb60972SMatt Spinler it->second.erase(pathIt);
1096eb60972SMatt Spinler }
1106eb60972SMatt Spinler
1116eb60972SMatt Spinler if (it->second.empty())
1126eb60972SMatt Spinler {
1136eb60972SMatt Spinler it = upstreamPorts.erase(it);
1146eb60972SMatt Spinler }
1156eb60972SMatt Spinler else
1166eb60972SMatt Spinler {
1176eb60972SMatt Spinler ++it;
1186eb60972SMatt Spinler }
1196eb60972SMatt Spinler }
1206eb60972SMatt Spinler
1216eb60972SMatt Spinler for (auto it = downstreamPorts.begin(); it != downstreamPorts.end();)
1226eb60972SMatt Spinler {
123b7077437SPatrick Williams auto pathIt =
124b7077437SPatrick Williams std::find(it->second.begin(), it->second.end(), boardPath);
1256eb60972SMatt Spinler if (pathIt != it->second.end())
1266eb60972SMatt Spinler {
1276eb60972SMatt Spinler it->second.erase(pathIt);
1286eb60972SMatt Spinler }
1296eb60972SMatt Spinler
1306eb60972SMatt Spinler if (it->second.empty())
1316eb60972SMatt Spinler {
1326eb60972SMatt Spinler it = downstreamPorts.erase(it);
1336eb60972SMatt Spinler }
1346eb60972SMatt Spinler else
1356eb60972SMatt Spinler {
1366eb60972SMatt Spinler ++it;
1376eb60972SMatt Spinler }
1386eb60972SMatt Spinler }
1396eb60972SMatt Spinler }
140