xref: /openbmc/entity-manager/src/topology.cpp (revision 5a80703cab896fcf5de2d5ed111dd4d1ab589709)
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