blob: 2745c088a05f36d9bb9ad06c2d29d60ac05198a6 [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
75 for (const std::pair<sdbusplus::message::object_path, SensorData>& sensor :
76 sensorConfigurations)
77 {
78 baseConfiguration = nullptr;
79 sensorData = &(sensor.second);
80
81 // match sensor type
82 auto sensorBase = sensorData->find(sensorType);
83 if (sensorBase == sensorData->end())
84 {
85 std::cerr << "error finding base configuration \n";
86 continue;
87 }
88
89 baseConfiguration = &(*sensorBase);
90
91 // judge class, "Gpio" or "I2C"
92 auto findClass = baseConfiguration->second.find("Class");
93 if (findClass != baseConfiguration->second.end() &&
Patrick Williams94733252020-05-13 11:44:58 -050094 std::get<std::string>(findClass->second) == "Gpio")
Qiang XUe28d1fa2019-02-27 13:50:56 +080095 {
96 *pType = IntrusionSensorType::gpio;
97 }
98 else
99 {
100 *pType = IntrusionSensorType::pch;
101 }
102
103 // case to find GPIO info
104 if (*pType == IntrusionSensorType::gpio)
105 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800106 auto findGpioPolarity =
107 baseConfiguration->second.find("GpioPolarity");
Qiang XUe28d1fa2019-02-27 13:50:56 +0800108
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800109 if (findGpioPolarity == baseConfiguration->second.end())
Qiang XUe28d1fa2019-02-27 13:50:56 +0800110 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800111 std::cerr << "error finding gpio polarity in configuration \n";
Qiang XUe28d1fa2019-02-27 13:50:56 +0800112 continue;
113 }
114
115 try
116 {
Qiang XUe28d1fa2019-02-27 13:50:56 +0800117 *pGpioInverted =
Patrick Williams94733252020-05-13 11:44:58 -0500118 (std::get<std::string>(findGpioPolarity->second) == "Low");
Qiang XUe28d1fa2019-02-27 13:50:56 +0800119 }
120 catch (const std::bad_variant_access& e)
121 {
122 std::cerr << "invalid value for gpio info in config. \n";
123 continue;
124 }
125
Ed Tanous8a57ec02020-10-09 12:46:52 -0700126 if (debug)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800127 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800128 std::cout << "find chassis intrusion sensor polarity inverted "
129 "flag is "
130 << *pGpioInverted << "\n";
Qiang XUe28d1fa2019-02-27 13:50:56 +0800131 }
132
133 return true;
134 }
135
136 // case to find I2C info
Ed Tanous8a57ec02020-10-09 12:46:52 -0700137 if (*pType == IntrusionSensorType::pch)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800138 {
139 auto findBus = baseConfiguration->second.find("Bus");
140 auto findAddress = baseConfiguration->second.find("Address");
141 if (findBus == baseConfiguration->second.end() ||
142 findAddress == baseConfiguration->second.end())
143 {
144 std::cerr << "error finding bus or address in configuration \n";
145 continue;
146 }
147
148 try
149 {
Patrick Williams94733252020-05-13 11:44:58 -0500150 *pBusId = std::get<uint64_t>(findBus->second);
151 *pSlaveAddr = std::get<uint64_t>(findAddress->second);
Qiang XUe28d1fa2019-02-27 13:50:56 +0800152 }
153 catch (const std::bad_variant_access& e)
154 {
155 std::cerr << "invalid value for bus or address in config. \n";
156 continue;
157 }
158
Ed Tanous8a57ec02020-10-09 12:46:52 -0700159 if (debug)
Qiang XUe28d1fa2019-02-27 13:50:56 +0800160 {
161 std::cout << "find matched bus " << *pBusId
162 << ", matched slave addr " << *pSlaveAddr << "\n";
163 }
164 return true;
165 }
166 }
167
Qiang XU74ddf862019-09-12 17:12:13 +0800168 std::cerr << "can't find matched I2C or GPIO configuration for intrusion "
169 "sensor. \n";
Qiang XUe28d1fa2019-02-27 13:50:56 +0800170 *pBusId = -1;
171 *pSlaveAddr = -1;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800172 return false;
173}
174
Qiang XU88b7f282019-08-14 22:51:43 +0800175static constexpr bool debugLanLeash = false;
176boost::container::flat_map<int, bool> lanStatusMap;
Qiang XU74ddf862019-09-12 17:12:13 +0800177boost::container::flat_map<int, std::string> lanInfoMap;
Qiang XU88b7f282019-08-14 22:51:43 +0800178boost::container::flat_map<std::string, int> pathSuffixMap;
179
Lei YUba637932021-03-17 10:35:00 +0800180static void getNicNameInfo(
181 const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
Qiang XU74ddf862019-09-12 17:12:13 +0800182{
183 auto getter = std::make_shared<GetSensorConfiguration>(
Zev Weissafd15042022-07-18 12:28:40 -0700184 dbusConnection, [](const ManagedObjectType& sensorConfigurations) {
185 // Get NIC name and save to map
186 lanInfoMap.clear();
187 for (const std::pair<sdbusplus::message::object_path, SensorData>&
188 sensor : sensorConfigurations)
Qiang XU74ddf862019-09-12 17:12:13 +0800189 {
Zev Weissafd15042022-07-18 12:28:40 -0700190 const std::pair<std::string, SensorBaseConfigMap>*
191 baseConfiguration = nullptr;
Qiang XU74ddf862019-09-12 17:12:13 +0800192
Zev Weissafd15042022-07-18 12:28:40 -0700193 // find base configuration
194 auto sensorBase = sensor.second.find(nicType);
195 if (sensorBase == sensor.second.end())
Qiang XU74ddf862019-09-12 17:12:13 +0800196 {
Zev Weissafd15042022-07-18 12:28:40 -0700197 continue;
198 }
199 baseConfiguration = &(*sensorBase);
200
201 auto findEthIndex = baseConfiguration->second.find("EthIndex");
202 auto findName = baseConfiguration->second.find("Name");
203
204 if (findEthIndex != baseConfiguration->second.end() &&
205 findName != baseConfiguration->second.end())
206 {
207 const auto* pEthIndex =
208 std::get_if<uint64_t>(&findEthIndex->second);
209 const auto* pName =
210 std::get_if<std::string>(&findName->second);
211 if (pEthIndex != nullptr && pName != nullptr)
Qiang XU74ddf862019-09-12 17:12:13 +0800212 {
Zev Weissafd15042022-07-18 12:28:40 -0700213 lanInfoMap[*pEthIndex] = *pName;
214 if (debugLanLeash)
215 {
216 std::cout << "find name of eth" << *pEthIndex
217 << " is " << *pName << "\n";
218 }
Qiang XU74ddf862019-09-12 17:12:13 +0800219 }
220 }
221 }
222
Zev Weissafd15042022-07-18 12:28:40 -0700223 if (lanInfoMap.empty())
224 {
225 std::cerr << "can't find matched NIC name. \n";
226 }
Ed Tanous8a17c302021-09-02 15:07:11 -0700227 });
Qiang XU74ddf862019-09-12 17:12:13 +0800228
229 getter->getConfiguration(
230 std::vector<std::string>{nicTypes.begin(), nicTypes.end()});
231}
232
Patrick Williams92f8f512022-07-22 19:26:55 -0500233static void processLanStatusChange(sdbusplus::message_t& message)
Qiang XU88b7f282019-08-14 22:51:43 +0800234{
235 const std::string& pathName = message.get_path();
236 std::string interfaceName;
Zev Weissafd15042022-07-18 12:28:40 -0700237 SensorBaseConfigMap properties;
Qiang XU88b7f282019-08-14 22:51:43 +0800238 message.read(interfaceName, properties);
239
240 auto findStateProperty = properties.find("OperationalState");
241 if (findStateProperty == properties.end())
242 {
243 return;
244 }
Qiang XU74ddf862019-09-12 17:12:13 +0800245 std::string* pState =
246 std::get_if<std::string>(&(findStateProperty->second));
Qiang XU88b7f282019-08-14 22:51:43 +0800247 if (pState == nullptr)
248 {
249 std::cerr << "invalid OperationalState \n";
250 return;
251 }
252
253 bool newLanConnected = (*pState == "routable" || *pState == "carrier" ||
254 *pState == "degraded");
255
256 // get ethNum from path. /org/freedesktop/network1/link/_32 for eth0
Brad Bishopfbb44ad2019-11-08 09:42:37 -0500257 size_t pos = pathName.find("/_");
Qiang XU88b7f282019-08-14 22:51:43 +0800258 if (pos == std::string::npos || pathName.length() <= pos + 2)
259 {
260 std::cerr << "unexpected path name " << pathName << "\n";
261 return;
262 }
263 std::string suffixStr = pathName.substr(pos + 2);
264
265 auto findEthNum = pathSuffixMap.find(suffixStr);
266 if (findEthNum == pathSuffixMap.end())
267 {
268 std::cerr << "unexpected eth for suffixStr " << suffixStr << "\n";
269 return;
270 }
271 int ethNum = findEthNum->second;
Qiang XU74ddf862019-09-12 17:12:13 +0800272
273 // get lan status from map
Qiang XU88b7f282019-08-14 22:51:43 +0800274 auto findLanStatus = lanStatusMap.find(ethNum);
275 if (findLanStatus == lanStatusMap.end())
276 {
277 std::cerr << "unexpected eth " << ethNum << " in lanStatusMap \n";
278 return;
279 }
280 bool oldLanConnected = findLanStatus->second;
281
Qiang XU74ddf862019-09-12 17:12:13 +0800282 // get lan info from map
Ed Tanous2049bd22022-07-09 07:20:26 -0700283 std::string lanInfo;
284 if (!lanInfoMap.empty())
Qiang XU74ddf862019-09-12 17:12:13 +0800285 {
286 auto findLanInfo = lanInfoMap.find(ethNum);
287 if (findLanInfo == lanInfoMap.end())
288 {
289 std::cerr << "unexpected eth " << ethNum << " in lanInfoMap \n";
290 }
291 else
292 {
293 lanInfo = "(" + findLanInfo->second + ")";
294 }
295 }
296
Qiang XU88b7f282019-08-14 22:51:43 +0800297 if (debugLanLeash)
298 {
299 std::cout << "ethNum = " << ethNum << ", state = " << *pState
300 << ", oldLanConnected = "
301 << (oldLanConnected ? "true" : "false")
302 << ", newLanConnected = "
303 << (newLanConnected ? "true" : "false") << "\n";
304 }
305
306 if (oldLanConnected != newLanConnected)
307 {
Qiang XU74ddf862019-09-12 17:12:13 +0800308 std::string strEthNum = "eth" + std::to_string(ethNum) + lanInfo;
Ed Tanous2049bd22022-07-09 07:20:26 -0700309 const auto* strState = newLanConnected ? "connected" : "lost";
310 const auto* strMsgId =
Qiang XU74ddf862019-09-12 17:12:13 +0800311 newLanConnected ? "OpenBMC.0.1.LanRegained" : "OpenBMC.0.1.LanLost";
Patrick Williams0c42f402021-08-27 16:05:45 -0500312
313 lg2::info("{ETHDEV} LAN leash {STATE}", "ETHDEV", strEthNum, "STATE",
314 strState, "REDFISH_MESSAGE_ID", strMsgId,
315 "REDFISH_MESSAGE_ARGS", strEthNum);
316
Qiang XU88b7f282019-08-14 22:51:43 +0800317 lanStatusMap[ethNum] = newLanConnected;
Qiang XU88b7f282019-08-14 22:51:43 +0800318 }
319}
320
Lei YUdd68d4a2021-03-16 22:17:23 +0800321/** @brief Initialize the lan status.
322 *
323 * @return true on success and false on failure
324 */
Lei YUba637932021-03-17 10:35:00 +0800325static bool initializeLanStatus(
326 const std::shared_ptr<sdbusplus::asio::connection>& conn)
Qiang XU88b7f282019-08-14 22:51:43 +0800327{
Qiang XU74ddf862019-09-12 17:12:13 +0800328 // init lan port name from configuration
329 getNicNameInfo(conn);
330
331 // get eth info from sysfs
Qiang XU88b7f282019-08-14 22:51:43 +0800332 std::vector<fs::path> files;
333 if (!findFiles(fs::path("/sys/class/net/"), R"(eth\d+/ifindex)", files))
334 {
335 std::cerr << "No eth in system\n";
Lei YUdd68d4a2021-03-16 22:17:23 +0800336 return false;
Qiang XU88b7f282019-08-14 22:51:43 +0800337 }
338
339 // iterate through all found eth files, and save ifindex
Ed Tanous8a57ec02020-10-09 12:46:52 -0700340 for (const fs::path& fileName : files)
Qiang XU88b7f282019-08-14 22:51:43 +0800341 {
342 if (debugLanLeash)
343 {
344 std::cout << "Reading " << fileName << "\n";
345 }
346 std::ifstream sysFile(fileName);
347 if (!sysFile.good())
348 {
349 std::cerr << "Failure reading " << fileName << "\n";
350 continue;
351 }
352 std::string line;
353 getline(sysFile, line);
354 const uint8_t ifindex = std::stoi(line);
355 // pathSuffix is ASCII of ifindex
356 const std::string& pathSuffix = std::to_string(ifindex + 30);
357
358 // extract ethNum
359 const std::string& fileStr = fileName.string();
360 const int pos = fileStr.find("eth");
361 const std::string& ethNumStr = fileStr.substr(pos + 3);
362 int ethNum = 0;
Ed Tanous8a57ec02020-10-09 12:46:52 -0700363 std::from_chars_result r = std::from_chars(
364 ethNumStr.data(), ethNumStr.data() + ethNumStr.size(), ethNum);
365 if (r.ec != std::errc())
Qiang XU88b7f282019-08-14 22:51:43 +0800366 {
367 std::cerr << "invalid ethNum string: " << ethNumStr << "\n";
368 continue;
369 }
370
371 // save pathSuffix
372 pathSuffixMap[pathSuffix] = ethNum;
373 if (debugLanLeash)
374 {
375 std::cout << "ethNum = " << std::to_string(ethNum)
376 << ", ifindex = " << line
377 << ", pathSuffix = " << pathSuffix << "\n";
378 }
379
Qiang XU74ddf862019-09-12 17:12:13 +0800380 // init lan connected status from networkd
Qiang XU88b7f282019-08-14 22:51:43 +0800381 conn->async_method_call(
382 [ethNum](boost::system::error_code ec,
383 const std::variant<std::string>& property) {
Ed Tanousbb679322022-05-16 16:10:00 -0700384 lanStatusMap[ethNum] = false;
385 if (ec)
386 {
387 std::cerr << "Error reading init status of eth" << ethNum
388 << "\n";
389 return;
390 }
391 const std::string* pState = std::get_if<std::string>(&property);
392 if (pState == nullptr)
393 {
394 std::cerr << "Unable to read lan status value\n";
395 return;
396 }
397 bool isLanConnected =
398 (*pState == "routable" || *pState == "carrier" ||
399 *pState == "degraded");
400 if (debugLanLeash)
401 {
402 std::cout << "ethNum = " << std::to_string(ethNum)
403 << ", init LAN status = "
404 << (isLanConnected ? "true" : "false") << "\n";
405 }
406 lanStatusMap[ethNum] = isLanConnected;
Qiang XU88b7f282019-08-14 22:51:43 +0800407 },
408 "org.freedesktop.network1",
409 "/org/freedesktop/network1/link/_" + pathSuffix,
410 "org.freedesktop.DBus.Properties", "Get",
411 "org.freedesktop.network1.Link", "OperationalState");
412 }
Lei YUdd68d4a2021-03-16 22:17:23 +0800413 return true;
Qiang XU88b7f282019-08-14 22:51:43 +0800414}
415
Qiang XUe28d1fa2019-02-27 13:50:56 +0800416int main()
417{
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800418 int busId = -1;
419 int slaveAddr = -1;
Qiang XUe28d1fa2019-02-27 13:50:56 +0800420 bool gpioInverted = false;
421 IntrusionSensorType type = IntrusionSensorType::gpio;
422
423 // setup connection to dbus
424 boost::asio::io_service io;
425 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
426 auto objServer = sdbusplus::asio::object_server(systemBus);
427
428 // setup object server, define interface
429 systemBus->request_name("xyz.openbmc_project.IntrusionSensor");
430
431 std::shared_ptr<sdbusplus::asio::dbus_interface> ifaceChassis =
432 objServer.add_interface(
433 "/xyz/openbmc_project/Intrusion/Chassis_Intrusion",
434 "xyz.openbmc_project.Chassis.Intrusion");
435
436 ChassisIntrusionSensor chassisIntrusionSensor(io, ifaceChassis);
437
438 if (getIntrusionSensorConfig(systemBus, &type, &busId, &slaveAddr,
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800439 &gpioInverted))
Qiang XUe28d1fa2019-02-27 13:50:56 +0800440 {
ZhikuiRenba8a8bf2020-01-09 15:55:43 -0800441 chassisIntrusionSensor.start(type, busId, slaveAddr, gpioInverted);
Qiang XUe28d1fa2019-02-27 13:50:56 +0800442 }
443
444 // callback to handle configuration change
Patrick Williams92f8f512022-07-22 19:26:55 -0500445 std::function<void(sdbusplus::message_t&)> eventHandler =
446 [&](sdbusplus::message_t& message) {
Ed Tanousbb679322022-05-16 16:10:00 -0700447 if (message.is_method_error())
448 {
449 std::cerr << "callback method error\n";
450 return;
451 }
Qiang XUe28d1fa2019-02-27 13:50:56 +0800452
Ed Tanousbb679322022-05-16 16:10:00 -0700453 std::cout << "rescan due to configuration change \n";
454 if (getIntrusionSensorConfig(systemBus, &type, &busId, &slaveAddr,
455 &gpioInverted))
456 {
457 chassisIntrusionSensor.start(type, busId, slaveAddr, gpioInverted);
458 }
459 };
Qiang XUe28d1fa2019-02-27 13:50:56 +0800460
Patrick Williams92f8f512022-07-22 19:26:55 -0500461 auto eventMatch = std::make_unique<sdbusplus::bus::match_t>(
462 static_cast<sdbusplus::bus_t&>(*systemBus),
Qiang XUe28d1fa2019-02-27 13:50:56 +0800463 "type='signal',member='PropertiesChanged',path_namespace='" +
464 std::string(inventoryPath) + "',arg0namespace='" + sensorType + "'",
465 eventHandler);
466
Lei YUdd68d4a2021-03-16 22:17:23 +0800467 if (initializeLanStatus(systemBus))
468 {
469 // add match to monitor lan status change
Patrick Williams92f8f512022-07-22 19:26:55 -0500470 sdbusplus::bus::match_t lanStatusMatch(
471 static_cast<sdbusplus::bus_t&>(*systemBus),
Lei YUdd68d4a2021-03-16 22:17:23 +0800472 "type='signal', member='PropertiesChanged',"
473 "arg0namespace='org.freedesktop.network1.Link'",
Patrick Williams92f8f512022-07-22 19:26:55 -0500474 [](sdbusplus::message_t& msg) { processLanStatusChange(msg); });
Lei YUdd68d4a2021-03-16 22:17:23 +0800475
476 // add match to monitor entity manager signal about nic name config
477 // change
Patrick Williams92f8f512022-07-22 19:26:55 -0500478 sdbusplus::bus::match_t lanConfigMatch(
479 static_cast<sdbusplus::bus_t&>(*systemBus),
Lei YUdd68d4a2021-03-16 22:17:23 +0800480 "type='signal', member='PropertiesChanged',path_namespace='" +
481 std::string(inventoryPath) + "',arg0namespace='" + nicType +
482 "'",
Patrick Williams92f8f512022-07-22 19:26:55 -0500483 [&systemBus](sdbusplus::message_t& msg) {
Ed Tanousbb679322022-05-16 16:10:00 -0700484 if (msg.is_method_error())
485 {
486 std::cerr << "callback method error\n";
487 return;
488 }
489 getNicNameInfo(systemBus);
Lei YUdd68d4a2021-03-16 22:17:23 +0800490 });
491 }
Qiang XU88b7f282019-08-14 22:51:43 +0800492
Qiang XUe28d1fa2019-02-27 13:50:56 +0800493 io.run();
494
495 return 0;
496}