1 #include "topology.hpp" 2 3 #include <iostream> 4 5 void Topology::addBoard(const std::string& path, const std::string& boardType, 6 const std::string& boardName, 7 const nlohmann::json& exposesItem) 8 { 9 auto findType = exposesItem.find("Type"); 10 if (findType == exposesItem.end()) 11 { 12 return; 13 } 14 15 boardNames.try_emplace(boardName, path); 16 17 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; 32 auto findPoweredBy = exposesItem.find("PowerPort"); 33 if (findPoweredBy != exposesItem.end()) 34 { 35 powerPaths.insert(path); 36 } 37 } 38 else if (exposesType.ends_with("Port")) 39 { 40 upstreamPorts[exposesType].emplace_back(path); 41 boardTypes[path] = boardType; 42 } 43 } 44 45 std::unordered_map<std::string, std::vector<Association>> 46 Topology::getAssocs(const std::map<Path, BoardName>& boards) 47 { 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 { 68 // 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); 73 if (powerPaths.find(downstream) != powerPaths.end()) 74 { 75 result[upstream].emplace_back( 76 "powered_by", "powering", downstream); 77 } 78 } 79 } 80 } 81 } 82 } 83 84 return result; 85 } 86 87 void 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 { 104 auto pathIt = std::find(it->second.begin(), it->second.end(), 105 boardPath); 106 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 { 123 auto pathIt = std::find(it->second.begin(), it->second.end(), 124 boardPath); 125 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 } 140