blob: caa6f93e15cb7f239c457d1bacccef0bd12067ab [file] [log] [blame]
Qiang XUe28d1fa2019-02-27 13:50:56 +08001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
Ed Tanous8a57ec02020-10-09 12:46:52 -070017#include <ChassisIntrusionSensor.hpp>
18#include <Utils.hpp>
Qiang XUe28d1fa2019-02-27 13:50:56 +080019#include <boost/algorithm/string/predicate.hpp>
Ed Tanous8a57ec02020-10-09 12:46:52 -070020#include <boost/asio/io_service.hpp>
Patrick Venture96e97db2019-10-31 13:44:38 -070021#include <boost/container/flat_map.hpp>
Patrick Williams0c42f402021-08-27 16:05:45 -050022#include <phosphor-logging/lg2.hpp>
Qiang XUe28d1fa2019-02-27 13:50:56 +080023#include <sdbusplus/asio/connection.hpp>
24#include <sdbusplus/asio/object_server.hpp>
25#include <sdbusplus/asio/sd_event.hpp>
26#include <sdbusplus/bus.hpp>
Patrick Venture96e97db2019-10-31 13:44:38 -070027#include <sdbusplus/bus/match.hpp>
Qiang XUe28d1fa2019-02-27 13:50:56 +080028#include <sdbusplus/exception.hpp>
29#include <sdbusplus/server.hpp>
30#include <sdbusplus/timer.hpp>
James Feist38fb5982020-05-28 10:09:54 -070031
32#include <array>
Ed Tanous8a57ec02020-10-09 12:46:52 -070033#include <charconv>
James Feist38fb5982020-05-28 10:09:54 -070034#include <chrono>
35#include <ctime>
36#include <fstream>
37#include <functional>
38#include <iostream>
39#include <memory>
Patrick Venture96e97db2019-10-31 13:44:38 -070040#include <stdexcept>
41#include <string>
42#include <utility>
43#include <vector>
Qiang XUe28d1fa2019-02-27 13:50:56 +080044
Ed Tanous8a57ec02020-10-09 12:46:52 -070045static constexpr bool debug = false;
Qiang XUe28d1fa2019-02-27 13:50:56 +080046
47static constexpr const char* sensorType =
48 "xyz.openbmc_project.Configuration.ChassisIntrusionSensor";
Qiang XU74ddf862019-09-12 17:12:13 +080049static constexpr const char* nicType = "xyz.openbmc_project.Configuration.NIC";
Brandon Kim66558232021-11-09 16:53:08 -080050static constexpr auto nicTypes{std::to_array<const char*>({nicType})};
Qiang XUe28d1fa2019-02-27 13:50:56 +080051
Qiang XU88b7f282019-08-14 22:51:43 +080052namespace fs = std::filesystem;
53
Qiang XUe28d1fa2019-02-27 13:50:56 +080054static bool getIntrusionSensorConfig(
Lei YUba637932021-03-17 10:35:00 +080055 const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
ZhikuiRenba8a8bf2020-01-09 15:55:43 -080056 IntrusionSensorType* pType, int* pBusId, int* pSlaveAddr,
Qiang XUe28d1fa2019-02-27 13:50:56 +080057 bool* pGpioInverted)
58{
59 // find matched configuration according to sensor type
60 ManagedObjectType sensorConfigurations;
61 bool useCache = false;
62
63 if (!getSensorConfiguration(sensorType, dbusConnection,
64 sensorConfigurations, useCache))
65 {
66 std::cerr << "error communicating to entity manager\n";
67 return false;
68 }
69
70 const SensorData* sensorData = nullptr;
Zev Weissafd15042022-07-18 12:28:40 -070071 const std::pair<std::string, SensorBaseConfigMap>* baseConfiguration =
72 nullptr;
Qiang XUe28d1fa2019-02-27 13:50:56 +080073
74 // Get bus and addr of matched configuration
Zev Weissf343b8a2022-08-12 18:21:01 -070075 for (const auto& [path, cfgData] : sensorConfigurations)
Qiang XUe28d1fa2019-02-27 13:50:56 +080076 {
77 baseConfiguration = nullptr;
Zev Weissf343b8a2022-08-12 18:21:01 -070078 sensorData = &cfgData;
Qiang XUe28d1fa2019-02-27 13:50:56 +080079
80 // match sensor type
81 auto sensorBase = sensorData->find(sensorType);
82 if (sensorBase == sensorData->end())
83 {
84 std::cerr << "error finding base configuration \n";
85 continue;
86 }
87
88 baseConfiguration = &(*sensorBase);
89
90 // judge class, "Gpio" or "I2C"
91 auto findClass = baseConfiguration->second.find("Class");
92 if (findClass != baseConfiguration->second.end() &&
Patrick Williams94733252020-05-13 11:44:58 -050093 std::get<std::string>(findClass->second) == "Gpio")
Qiang XUe28d1fa2019-02-27 13:50:56 +080094 {
95 *pType = IntrusionSensorType::gpio;
96 }
97 else
98 {
99 *pType = IntrusionSensorType::pch;
100 }
101
102 // case to find GPIO info
103 if (*pType == IntrusionSensorType::gpio)
104 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800105 auto findGpioPolarity =
106 baseConfiguration->second.find("GpioPolarity");
Qiang XUe28d1fa2019-02-27 13:50:56 +0800107
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800108 if (findGpioPolarity == baseConfiguration->second.end())
Qiang XUe28d1fa2019-02-27 13:50:56 +0800109 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800110 std::cerr << "error finding gpio polarity in configuration \n";
Qiang XUe28d1fa2019-02-27 13:50:56 +0800111 continue;
112 }
113
114 try
115 {
Qiang XUe28d1fa2019-02-27 13:50:56 +0800116 *pGpioInverted =
Patrick Williams94733252020-05-13 11:44:58 -0500117 (std::get<std::string>(findGpioPolarity->second) == "Low");
Qiang XUe28d1fa2019-02-27 13:50:56 +0800118 }
119 catch (const std::bad_variant_access& e)
120 {
121 std::cerr << "invalid value for gpio info in config. \n";
122 continue;
123 }
124
Ed Tanous8a57ec02020-10-09 12:46:52 -0700125 if (debug)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800126 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800127 std::cout << "find chassis intrusion sensor polarity inverted "
128 "flag is "
129 << *pGpioInverted << "\n";
Qiang XUe28d1fa2019-02-27 13:50:56 +0800130 }
131
132 return true;
133 }
134
135 // case to find I2C info
Ed Tanous8a57ec02020-10-09 12:46:52 -0700136 if (*pType == IntrusionSensorType::pch)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800137 {
138 auto findBus = baseConfiguration->second.find("Bus");
139 auto findAddress = baseConfiguration->second.find("Address");
140 if (findBus == baseConfiguration->second.end() ||
141 findAddress == baseConfiguration->second.end())
142 {
143 std::cerr << "error finding bus or address in configuration \n";
144 continue;
145 }
146
147 try
148 {
Patrick Williams94733252020-05-13 11:44:58 -0500149 *pBusId = std::get<uint64_t>(findBus->second);
150 *pSlaveAddr = std::get<uint64_t>(findAddress->second);
Qiang XUe28d1fa2019-02-27 13:50:56 +0800151 }
152 catch (const std::bad_variant_access& e)
153 {
154 std::cerr << "invalid value for bus or address in config. \n";
155 continue;
156 }
157
Ed Tanous8a57ec02020-10-09 12:46:52 -0700158 if (debug)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800159 {
160 std::cout << "find matched bus " << *pBusId
161 << ", matched slave addr " << *pSlaveAddr << "\n";
162 }
163 return true;
164 }
165 }
166
Qiang XU74ddf862019-09-12 17:12:13 +0800167 std::cerr << "can't find matched I2C or GPIO configuration for intrusion "
168 "sensor. \n";
Qiang XUe28d1fa2019-02-27 13:50:56 +0800169 *pBusId = -1;
170 *pSlaveAddr = -1;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800171 return false;
172}
173
Qiang XU88b7f282019-08-14 22:51:43 +0800174static constexpr bool debugLanLeash = false;
175boost::container::flat_map<int, bool> lanStatusMap;
Qiang XU74ddf862019-09-12 17:12:13 +0800176boost::container::flat_map<int, std::string> lanInfoMap;
Qiang XU88b7f282019-08-14 22:51:43 +0800177boost::container::flat_map<std::string, int> pathSuffixMap;
178
Lei YUba637932021-03-17 10:35:00 +0800179static void getNicNameInfo(
180 const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
Qiang XU74ddf862019-09-12 17:12:13 +0800181{
182 auto getter = std::make_shared<GetSensorConfiguration>(
Zev Weissafd15042022-07-18 12:28:40 -0700183 dbusConnection, [](const ManagedObjectType& sensorConfigurations) {
184 // Get NIC name and save to map
185 lanInfoMap.clear();
Zev Weissf343b8a2022-08-12 18:21:01 -0700186 for (const auto& [path, cfgData] : sensorConfigurations)
Qiang XU74ddf862019-09-12 17:12:13 +0800187 {
Zev Weissafd15042022-07-18 12:28:40 -0700188 const std::pair<std::string, SensorBaseConfigMap>*
189 baseConfiguration = nullptr;
Qiang XU74ddf862019-09-12 17:12:13 +0800190
Zev Weissafd15042022-07-18 12:28:40 -0700191 // find base configuration
Zev Weissf343b8a2022-08-12 18:21:01 -0700192 auto sensorBase = cfgData.find(nicType);
193 if (sensorBase == cfgData.end())
Qiang XU74ddf862019-09-12 17:12:13 +0800194 {
Zev Weissafd15042022-07-18 12:28:40 -0700195 continue;
196 }
197 baseConfiguration = &(*sensorBase);
198
199 auto findEthIndex = baseConfiguration->second.find("EthIndex");
200 auto findName = baseConfiguration->second.find("Name");
201
202 if (findEthIndex != baseConfiguration->second.end() &&
203 findName != baseConfiguration->second.end())
204 {
205 const auto* pEthIndex =
206 std::get_if<uint64_t>(&findEthIndex->second);
207 const auto* pName =
208 std::get_if<std::string>(&findName->second);
209 if (pEthIndex != nullptr && pName != nullptr)
Qiang XU74ddf862019-09-12 17:12:13 +0800210 {
Zev Weissafd15042022-07-18 12:28:40 -0700211 lanInfoMap[*pEthIndex] = *pName;
212 if (debugLanLeash)
213 {
214 std::cout << "find name of eth" << *pEthIndex
215 << " is " << *pName << "\n";
216 }
Qiang XU74ddf862019-09-12 17:12:13 +0800217 }
218 }
219 }
220
Zev Weissafd15042022-07-18 12:28:40 -0700221 if (lanInfoMap.empty())
222 {
223 std::cerr << "can't find matched NIC name. \n";
224 }
Ed Tanous8a17c302021-09-02 15:07:11 -0700225 });
Qiang XU74ddf862019-09-12 17:12:13 +0800226
227 getter->getConfiguration(
228 std::vector<std::string>{nicTypes.begin(), nicTypes.end()});
229}
230
Patrick Williams92f8f512022-07-22 19:26:55 -0500231static void processLanStatusChange(sdbusplus::message_t& message)
Qiang XU88b7f282019-08-14 22:51:43 +0800232{
233 const std::string& pathName = message.get_path();
234 std::string interfaceName;
Zev Weissafd15042022-07-18 12:28:40 -0700235 SensorBaseConfigMap properties;
Qiang XU88b7f282019-08-14 22:51:43 +0800236 message.read(interfaceName, properties);
237
238 auto findStateProperty = properties.find("OperationalState");
239 if (findStateProperty == properties.end())
240 {
241 return;
242 }
Qiang XU74ddf862019-09-12 17:12:13 +0800243 std::string* pState =
244 std::get_if<std::string>(&(findStateProperty->second));
Qiang XU88b7f282019-08-14 22:51:43 +0800245 if (pState == nullptr)
246 {
247 std::cerr << "invalid OperationalState \n";
248 return;
249 }
250
251 bool newLanConnected = (*pState == "routable" || *pState == "carrier" ||
252 *pState == "degraded");
253
254 // get ethNum from path. /org/freedesktop/network1/link/_32 for eth0
Brad Bishopfbb44ad2019-11-08 09:42:37 -0500255 size_t pos = pathName.find("/_");
Qiang XU88b7f282019-08-14 22:51:43 +0800256 if (pos == std::string::npos || pathName.length() <= pos + 2)
257 {
258 std::cerr << "unexpected path name " << pathName << "\n";
259 return;
260 }
261 std::string suffixStr = pathName.substr(pos + 2);
262
263 auto findEthNum = pathSuffixMap.find(suffixStr);
264 if (findEthNum == pathSuffixMap.end())
265 {
266 std::cerr << "unexpected eth for suffixStr " << suffixStr << "\n";
267 return;
268 }
269 int ethNum = findEthNum->second;
Qiang XU74ddf862019-09-12 17:12:13 +0800270
271 // get lan status from map
Qiang XU88b7f282019-08-14 22:51:43 +0800272 auto findLanStatus = lanStatusMap.find(ethNum);
273 if (findLanStatus == lanStatusMap.end())
274 {
275 std::cerr << "unexpected eth " << ethNum << " in lanStatusMap \n";
276 return;
277 }
278 bool oldLanConnected = findLanStatus->second;
279
Qiang XU74ddf862019-09-12 17:12:13 +0800280 // get lan info from map
Ed Tanous2049bd22022-07-09 07:20:26 -0700281 std::string lanInfo;
282 if (!lanInfoMap.empty())
Qiang XU74ddf862019-09-12 17:12:13 +0800283 {
284 auto findLanInfo = lanInfoMap.find(ethNum);
285 if (findLanInfo == lanInfoMap.end())
286 {
287 std::cerr << "unexpected eth " << ethNum << " in lanInfoMap \n";
288 }
289 else
290 {
291 lanInfo = "(" + findLanInfo->second + ")";
292 }
293 }
294
Qiang XU88b7f282019-08-14 22:51:43 +0800295 if (debugLanLeash)
296 {
297 std::cout << "ethNum = " << ethNum << ", state = " << *pState
298 << ", oldLanConnected = "
299 << (oldLanConnected ? "true" : "false")
300 << ", newLanConnected = "
301 << (newLanConnected ? "true" : "false") << "\n";
302 }
303
304 if (oldLanConnected != newLanConnected)
305 {
Qiang XU74ddf862019-09-12 17:12:13 +0800306 std::string strEthNum = "eth" + std::to_string(ethNum) + lanInfo;
Ed Tanous2049bd22022-07-09 07:20:26 -0700307 const auto* strState = newLanConnected ? "connected" : "lost";
308 const auto* strMsgId =
Qiang XU74ddf862019-09-12 17:12:13 +0800309 newLanConnected ? "OpenBMC.0.1.LanRegained" : "OpenBMC.0.1.LanLost";
Patrick Williams0c42f402021-08-27 16:05:45 -0500310
311 lg2::info("{ETHDEV} LAN leash {STATE}", "ETHDEV", strEthNum, "STATE",
312 strState, "REDFISH_MESSAGE_ID", strMsgId,
313 "REDFISH_MESSAGE_ARGS", strEthNum);
314
Qiang XU88b7f282019-08-14 22:51:43 +0800315 lanStatusMap[ethNum] = newLanConnected;
Qiang XU88b7f282019-08-14 22:51:43 +0800316 }
317}
318
Lei YUdd68d4a2021-03-16 22:17:23 +0800319/** @brief Initialize the lan status.
320 *
321 * @return true on success and false on failure
322 */
Lei YUba637932021-03-17 10:35:00 +0800323static bool initializeLanStatus(
324 const std::shared_ptr<sdbusplus::asio::connection>& conn)
Qiang XU88b7f282019-08-14 22:51:43 +0800325{
Qiang XU74ddf862019-09-12 17:12:13 +0800326 // init lan port name from configuration
327 getNicNameInfo(conn);
328
329 // get eth info from sysfs
Qiang XU88b7f282019-08-14 22:51:43 +0800330 std::vector<fs::path> files;
331 if (!findFiles(fs::path("/sys/class/net/"), R"(eth\d+/ifindex)", files))
332 {
333 std::cerr << "No eth in system\n";
Lei YUdd68d4a2021-03-16 22:17:23 +0800334 return false;
Qiang XU88b7f282019-08-14 22:51:43 +0800335 }
336
337 // iterate through all found eth files, and save ifindex
Ed Tanous8a57ec02020-10-09 12:46:52 -0700338 for (const fs::path& fileName : files)
Qiang XU88b7f282019-08-14 22:51:43 +0800339 {
340 if (debugLanLeash)
341 {
342 std::cout << "Reading " << fileName << "\n";
343 }
344 std::ifstream sysFile(fileName);
345 if (!sysFile.good())
346 {
347 std::cerr << "Failure reading " << fileName << "\n";
348 continue;
349 }
350 std::string line;
351 getline(sysFile, line);
352 const uint8_t ifindex = std::stoi(line);
353 // pathSuffix is ASCII of ifindex
354 const std::string& pathSuffix = std::to_string(ifindex + 30);
355
356 // extract ethNum
357 const std::string& fileStr = fileName.string();
358 const int pos = fileStr.find("eth");
359 const std::string& ethNumStr = fileStr.substr(pos + 3);
360 int ethNum = 0;
Ed Tanous8a57ec02020-10-09 12:46:52 -0700361 std::from_chars_result r = std::from_chars(
362 ethNumStr.data(), ethNumStr.data() + ethNumStr.size(), ethNum);
363 if (r.ec != std::errc())
Qiang XU88b7f282019-08-14 22:51:43 +0800364 {
365 std::cerr << "invalid ethNum string: " << ethNumStr << "\n";
366 continue;
367 }
368
369 // save pathSuffix
370 pathSuffixMap[pathSuffix] = ethNum;
371 if (debugLanLeash)
372 {
373 std::cout << "ethNum = " << std::to_string(ethNum)
374 << ", ifindex = " << line
375 << ", pathSuffix = " << pathSuffix << "\n";
376 }
377
Qiang XU74ddf862019-09-12 17:12:13 +0800378 // init lan connected status from networkd
Qiang XU88b7f282019-08-14 22:51:43 +0800379 conn->async_method_call(
380 [ethNum](boost::system::error_code ec,
381 const std::variant<std::string>& property) {
Ed Tanousbb679322022-05-16 16:10:00 -0700382 lanStatusMap[ethNum] = false;
383 if (ec)
384 {
385 std::cerr << "Error reading init status of eth" << ethNum
386 << "\n";
387 return;
388 }
389 const std::string* pState = std::get_if<std::string>(&property);
390 if (pState == nullptr)
391 {
392 std::cerr << "Unable to read lan status value\n";
393 return;
394 }
395 bool isLanConnected =
396 (*pState == "routable" || *pState == "carrier" ||
397 *pState == "degraded");
398 if (debugLanLeash)
399 {
400 std::cout << "ethNum = " << std::to_string(ethNum)
401 << ", init LAN status = "
402 << (isLanConnected ? "true" : "false") << "\n";
403 }
404 lanStatusMap[ethNum] = isLanConnected;
Qiang XU88b7f282019-08-14 22:51:43 +0800405 },
406 "org.freedesktop.network1",
407 "/org/freedesktop/network1/link/_" + pathSuffix,
408 "org.freedesktop.DBus.Properties", "Get",
409 "org.freedesktop.network1.Link", "OperationalState");
410 }
Lei YUdd68d4a2021-03-16 22:17:23 +0800411 return true;
Qiang XU88b7f282019-08-14 22:51:43 +0800412}
413
Qiang XUe28d1fa2019-02-27 13:50:56 +0800414int main()
415{
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800416 int busId = -1;
417 int slaveAddr = -1;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800418 bool gpioInverted = false;
419 IntrusionSensorType type = IntrusionSensorType::gpio;
420
421 // setup connection to dbus
422 boost::asio::io_service io;
423 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
424 auto objServer = sdbusplus::asio::object_server(systemBus);
425
426 // setup object server, define interface
427 systemBus->request_name("xyz.openbmc_project.IntrusionSensor");
428
429 std::shared_ptr<sdbusplus::asio::dbus_interface> ifaceChassis =
430 objServer.add_interface(
431 "/xyz/openbmc_project/Intrusion/Chassis_Intrusion",
432 "xyz.openbmc_project.Chassis.Intrusion");
433
434 ChassisIntrusionSensor chassisIntrusionSensor(io, ifaceChassis);
435
436 if (getIntrusionSensorConfig(systemBus, &type, &busId, &slaveAddr,
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800437 &gpioInverted))
Qiang XUe28d1fa2019-02-27 13:50:56 +0800438 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800439 chassisIntrusionSensor.start(type, busId, slaveAddr, gpioInverted);
Qiang XUe28d1fa2019-02-27 13:50:56 +0800440 }
441
442 // callback to handle configuration change
Patrick Williams92f8f512022-07-22 19:26:55 -0500443 std::function<void(sdbusplus::message_t&)> eventHandler =
444 [&](sdbusplus::message_t& message) {
Ed Tanousbb679322022-05-16 16:10:00 -0700445 if (message.is_method_error())
446 {
447 std::cerr << "callback method error\n";
448 return;
449 }
Qiang XUe28d1fa2019-02-27 13:50:56 +0800450
Ed Tanousbb679322022-05-16 16:10:00 -0700451 std::cout << "rescan due to configuration change \n";
452 if (getIntrusionSensorConfig(systemBus, &type, &busId, &slaveAddr,
453 &gpioInverted))
454 {
455 chassisIntrusionSensor.start(type, busId, slaveAddr, gpioInverted);
456 }
457 };
Qiang XUe28d1fa2019-02-27 13:50:56 +0800458
Zev Weiss214d9712022-08-12 12:54:31 -0700459 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
460 setupPropertiesChangedMatches(
461 *systemBus, std::to_array<const char*>({sensorType}), eventHandler);
Qiang XUe28d1fa2019-02-27 13:50:56 +0800462
Lei YUdd68d4a2021-03-16 22:17:23 +0800463 if (initializeLanStatus(systemBus))
464 {
465 // add match to monitor lan status change
Patrick Williams92f8f512022-07-22 19:26:55 -0500466 sdbusplus::bus::match_t lanStatusMatch(
467 static_cast<sdbusplus::bus_t&>(*systemBus),
Lei YUdd68d4a2021-03-16 22:17:23 +0800468 "type='signal', member='PropertiesChanged',"
469 "arg0namespace='org.freedesktop.network1.Link'",
Patrick Williams92f8f512022-07-22 19:26:55 -0500470 [](sdbusplus::message_t& msg) { processLanStatusChange(msg); });
Lei YUdd68d4a2021-03-16 22:17:23 +0800471
472 // add match to monitor entity manager signal about nic name config
473 // change
Patrick Williams92f8f512022-07-22 19:26:55 -0500474 sdbusplus::bus::match_t lanConfigMatch(
475 static_cast<sdbusplus::bus_t&>(*systemBus),
Lei YUdd68d4a2021-03-16 22:17:23 +0800476 "type='signal', member='PropertiesChanged',path_namespace='" +
477 std::string(inventoryPath) + "',arg0namespace='" + nicType +
478 "'",
Patrick Williams92f8f512022-07-22 19:26:55 -0500479 [&systemBus](sdbusplus::message_t& msg) {
Ed Tanousbb679322022-05-16 16:10:00 -0700480 if (msg.is_method_error())
481 {
482 std::cerr << "callback method error\n";
483 return;
484 }
485 getNicNameInfo(systemBus);
Lei YUdd68d4a2021-03-16 22:17:23 +0800486 });
487 }
Qiang XU88b7f282019-08-14 22:51:43 +0800488
Qiang XUe28d1fa2019-02-27 13:50:56 +0800489 io.run();
490
491 return 0;
492}