blob: 168c160fe9a300721496a6610028fc81f60dffb2 [file] [log] [blame]
#include "topology.hpp"
#include <iostream>
void Topology::addBoard(const std::string& path, const std::string& boardType,
const std::string& boardName,
const nlohmann::json& exposesItem)
{
auto findType = exposesItem.find("Type");
if (findType == exposesItem.end())
{
return;
}
boardNames.try_emplace(boardName, path);
PortType exposesType = findType->get<std::string>();
if (exposesType == "DownstreamPort")
{
auto findConnectsTo = exposesItem.find("ConnectsToType");
if (findConnectsTo == exposesItem.end())
{
std::cerr << "Board at path " << path
<< " is missing ConnectsToType" << std::endl;
return;
}
PortType connectsTo = findConnectsTo->get<std::string>();
downstreamPorts[connectsTo].emplace_back(path);
boardTypes[path] = boardType;
auto findPoweredBy = exposesItem.find("PowerPort");
if (findPoweredBy != exposesItem.end())
{
powerPaths.insert(path);
}
}
else if (exposesType.ends_with("Port"))
{
upstreamPorts[exposesType].emplace_back(path);
boardTypes[path] = boardType;
}
}
std::unordered_map<std::string, std::vector<Association>>
Topology::getAssocs(const std::map<Path, BoardName>& boards)
{
std::unordered_map<std::string, std::vector<Association>> result;
// look at each upstream port type
for (const auto& upstreamPortPair : upstreamPorts)
{
auto downstreamMatch = downstreamPorts.find(upstreamPortPair.first);
if (downstreamMatch == downstreamPorts.end())
{
// no match
continue;
}
for (const Path& upstream : upstreamPortPair.second)
{
if (boardTypes[upstream] == "Chassis" ||
boardTypes[upstream] == "Board")
{
for (const Path& downstream : downstreamMatch->second)
{
// The downstream path must be one we care about.
if (boards.find(downstream) != boards.end())
{
result[downstream].emplace_back("contained_by",
"containing", upstream);
if (powerPaths.find(downstream) != powerPaths.end())
{
result[upstream].emplace_back(
"powered_by", "powering", downstream);
}
}
}
}
}
}
return result;
}
void Topology::remove(const std::string& boardName)
{
// Remove the board from boardNames, and then using the path
// found in boardNames remove it from upstreamPorts and
// downstreamPorts.
auto boardFind = boardNames.find(boardName);
if (boardFind == boardNames.end())
{
return;
}
std::string boardPath = boardFind->second;
boardNames.erase(boardFind);
for (auto it = upstreamPorts.begin(); it != upstreamPorts.end();)
{
auto pathIt =
std::find(it->second.begin(), it->second.end(), boardPath);
if (pathIt != it->second.end())
{
it->second.erase(pathIt);
}
if (it->second.empty())
{
it = upstreamPorts.erase(it);
}
else
{
++it;
}
}
for (auto it = downstreamPorts.begin(); it != downstreamPorts.end();)
{
auto pathIt =
std::find(it->second.begin(), it->second.end(), boardPath);
if (pathIt != it->second.end())
{
it->second.erase(pathIt);
}
if (it->second.empty())
{
it = downstreamPorts.erase(it);
}
else
{
++it;
}
}
}