blob: ad0b8b4efa18ce09255f9d41f38b61273e9cf0a8 [file] [log] [blame]
Asmitha Karunanithibe2bdec2021-05-13 02:54:29 -05001#include "hyp_network_manager.hpp"
2
3#include "types.hpp"
4#include "util.hpp"
5
6#include <phosphor-logging/elog-errors.hpp>
7#include <phosphor-logging/elog.hpp>
8#include <phosphor-logging/log.hpp>
9#include <sdbusplus/bus.hpp>
10#include <sdbusplus/server/object.hpp>
11#include <xyz/openbmc_project/Common/error.hpp>
12
13using sdbusplus::exception::SdBusError;
14
15class HypNetworkMgr;
16
17namespace phosphor
18{
19namespace network
20{
21using namespace phosphor::logging;
22using InternalFailure =
23 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
24
25const std::string intType = "Integer";
26const std::string strType = "String";
27const std::string enumType = "Enumeration";
28
29using ObjectTree =
30 std::map<std::string, std::map<std::string, std::vector<std::string>>>;
31
32auto HypNetworkMgr::getDBusProp(const std::string& objectName,
33 const std::string& interface,
34 const std::string& kw)
35{
36 auto bus = sdbusplus::bus::new_default();
37 auto properties = bus.new_method_call(
38 "xyz.openbmc_project.BIOSConfigManager", objectName.c_str(),
39 "org.freedesktop.DBus.Properties", "Get");
40 properties.append(interface);
41 properties.append(kw);
42 auto result = bus.call(properties);
43
44 if (result.is_method_error())
45 {
46 throw std::runtime_error("Get api failed");
47 }
48 return result;
49}
50
51void HypNetworkMgr::setBIOSTableAttr(
52 std::string attrName, std::variant<std::string, int64_t> attrValue,
53 std::string attrType)
54{
55 auto findAttr = biosTableAttrs.find(attrName);
56 if (findAttr != biosTableAttrs.end())
57 {
58 if (attrType == intType)
59 {
60 int64_t value = std::get<int64_t>(attrValue);
61 if (value != std::get<int64_t>(findAttr->second))
62 {
63 biosTableAttrs.erase(findAttr);
64 biosTableAttrs.emplace(attrName, value);
65 }
66 }
67 else if (attrType == strType)
68 {
69 std::string value = std::get<std::string>(attrValue);
70 if (value != std::get<std::string>(findAttr->second))
71 {
72 biosTableAttrs.erase(findAttr);
73 biosTableAttrs.emplace(attrName, value);
74 }
75 }
76 }
77 else
78 {
79 log<level::INFO>(
80 "setBIOSTableAttr: Attribute is not found in biosTableAttrs"),
81 entry("attrName : ", attrName.c_str());
82 }
83}
84
85void HypNetworkMgr::setBIOSTableAttrs()
86{
87 try
88 {
89 constexpr auto biosMgrIntf = "xyz.openbmc_project.BIOSConfig.Manager";
90 constexpr auto biosMgrObj = "/xyz/openbmc_project/bios_config";
91
92 constexpr auto mapperBus = "xyz.openbmc_project.ObjectMapper";
93 constexpr auto mapperObj = "/xyz/openbmc_project/object_mapper";
94 constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
95
96 std::vector<std::string> interfaces;
97 interfaces.emplace_back(biosMgrIntf);
98 auto depth = 0;
99
100 auto mapperCall =
101 bus.new_method_call(mapperBus, mapperObj, mapperIntf, "GetSubTree");
102
103 mapperCall.append(biosMgrObj, depth, interfaces);
104
105 auto mapperReply = bus.call(mapperCall);
106 if (mapperReply.is_method_error())
107 {
108 log<level::ERR>("Error in mapper call");
109 elog<InternalFailure>();
110 }
111
112 ObjectTree objectTree;
113 mapperReply.read(objectTree);
114
115 if (objectTree.empty())
116 {
117 log<level::ERR>("No Object has implemented the interface",
118 entry("INTERFACE=%s", biosMgrIntf));
119 elog<InternalFailure>();
120 }
121
122 std::string objPath;
123
124 if (1 == objectTree.size())
125 {
126 objPath = objectTree.begin()->first;
127 }
128 else
129 {
130 // If there are more than 2 objects, object path must contain the
131 // interface name
132 for (auto const& object : objectTree)
133 {
134 log<level::INFO>("interface", entry("INT=%s", biosMgrIntf));
135 log<level::INFO>("object",
136 entry("OBJ=%s", object.first.c_str()));
137
138 if (std::string::npos != object.first.find(biosMgrIntf))
139 {
140 objPath = object.first;
141 break;
142 }
143 }
144
145 if (objPath.empty())
146 {
147 log<level::ERR>("Can't find the object for the interface",
148 entry("intfName=%s", biosMgrIntf));
149 elog<InternalFailure>();
150 }
151 }
152
153 std::variant<BiosBaseTableType> response;
154 getDBusProp(objPath, biosMgrIntf, "BaseBIOSTable").read(response);
155
156 const BiosBaseTableType* baseBiosTable =
157 std::get_if<BiosBaseTableType>(&response);
158
159 if (baseBiosTable == nullptr)
160 {
161 log<level::ERR>("BaseBiosTable is empty. No attributes found!");
162 return;
163 }
164
165 for (const BiosBaseTableItemType& item : *baseBiosTable)
166 {
167 if (item.first.rfind("vmi", 0) == 0) // starts with the prefix
168 {
169 const std::string& itemType =
170 std::get<biosBaseAttrType>(item.second);
171
172 if (itemType.compare(itemType.size() - intType.size(),
173 intType.size(), intType) == 0)
174 {
175 const int64_t* currValue = std::get_if<int64_t>(
176 &std::get<biosBaseCurrValue>(item.second));
177 if (currValue != nullptr)
178 {
179 if (item.first == "vmi_if_count")
180 {
181 intfCount = *currValue;
182 }
183 biosTableAttrs.emplace(item.first, *currValue);
184 }
185 }
186 else if ((itemType.compare(itemType.size() - strType.size(),
187 strType.size(), strType) == 0) ||
188 (itemType.compare(itemType.size() - enumType.size(),
189 enumType.size(), enumType) == 0))
190 {
191 const std::string* currValue = std::get_if<std::string>(
192 &std::get<biosBaseCurrValue>(item.second));
193 if (currValue != nullptr)
194 {
195 biosTableAttrs.emplace(item.first, *currValue);
196 }
197 }
198 else
199 {
200 log<level::ERR>("Unsupported datatype: The attribute is of "
201 "unknown type");
202 }
203 }
204 }
205 }
206 catch (const SdBusError& e)
207 {
208 log<level::ERR>("Error in making dbus call");
209 throw std::runtime_error("DBus call failed");
210 }
211}
212
213uint16_t HypNetworkMgr::getIntfCount()
214{
215 return intfCount;
216}
217
218biosTableType HypNetworkMgr::getBIOSTableAttrs()
219{
220 return biosTableAttrs;
221}
222
223void HypNetworkMgr::createIfObjects()
224{
225 setBIOSTableAttrs();
226
227 if (intfCount == 1)
228 {
229 // TODO: create eth0 object
230 log<level::INFO>("Create eth0 object");
231 }
232 else if (intfCount == 2)
233 {
234 // TODO: create eth0 and eth1 objects
235 log<level::INFO>("Create eth0 and eth1 objects");
236 }
237 else
238 {
239 log<level::ERR>("More than 2 Interfaces");
240 return;
241 }
242}
243
244} // namespace network
245} // namespace phosphor