blob: d66e5be5ad13175b055388611b7eb378b26a2742 [file] [log] [blame]
Cheng C Yang209ec562019-03-12 16:37:44 +08001/*
2// Copyright (c) 2019 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
Cheng C Yang58b2b532019-05-31 00:19:45 +080017#include <PSUEvent.hpp>
Cheng C Yang209ec562019-03-12 16:37:44 +080018#include <PSUSensor.hpp>
19#include <Utils.hpp>
20#include <boost/algorithm/string/predicate.hpp>
21#include <boost/algorithm/string/replace.hpp>
22#include <boost/container/flat_set.hpp>
James Feist24f02f22019-04-15 11:05:39 -070023#include <filesystem>
Cheng C Yang209ec562019-03-12 16:37:44 +080024#include <fstream>
Cheng C Yang58b2b532019-05-31 00:19:45 +080025#include <iostream>
Cheng C Yang209ec562019-03-12 16:37:44 +080026#include <regex>
27#include <sdbusplus/asio/connection.hpp>
28#include <sdbusplus/asio/object_server.hpp>
29
30static constexpr std::array<const char*, 1> sensorTypes = {
31 "xyz.openbmc_project.Configuration.pmbus"};
32
Vijay Khemkaa0b731d2019-07-24 15:58:48 -070033static std::vector<std::string> pmbusNames = {"pmbus", "pxe1610", "ina219",
34 "ina230"};
Cheng C Yang209ec562019-03-12 16:37:44 +080035namespace fs = std::filesystem;
36
Cheng C Yang916360b2019-05-07 18:47:16 +080037static boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>>
38 sensors;
Cheng C Yang58b2b532019-05-31 00:19:45 +080039static boost::container::flat_map<std::string, std::unique_ptr<PSUCombineEvent>>
40 combineEvents;
Cheng C Yang916360b2019-05-07 18:47:16 +080041static boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
42 pwmSensors;
43static boost::container::flat_map<std::string, std::string> sensorTable;
44static boost::container::flat_map<std::string, PSUProperty> labelMatch;
45static boost::container::flat_map<std::string, std::string> pwmTable;
Cheng C Yang58b2b532019-05-31 00:19:45 +080046static boost::container::flat_map<std::string, std::vector<std::string>>
47 eventMatch;
48static boost::container::flat_map<std::string, std::vector<std::string>>
49 limitEventMatch;
50
51// Function CheckEvent will check each attribute from eventMatch table in the
52// sysfs. If the attributes exists in sysfs, then store the complete path
53// of the attribute into eventPathList.
54void checkEvent(
55 const std::string& directory,
56 const boost::container::flat_map<std::string, std::vector<std::string>>&
57 eventMatch,
58 boost::container::flat_map<std::string, std::vector<std::string>>&
59 eventPathList)
60{
61 for (const auto& match : eventMatch)
62 {
63 const std::vector<std::string>& eventAttrs = match.second;
64 const std::string& eventName = match.first;
65 for (const auto& eventAttr : eventAttrs)
66 {
67 auto eventPath = directory + "/" + eventAttr;
68
69 std::ifstream eventFile(eventPath);
70 if (!eventFile.good())
71 {
72 continue;
73 }
74
75 eventPathList[eventName].push_back(eventPath);
76 }
77 }
78}
79
80// Function checkEventLimits will check all the psu related xxx_input attributes
81// in sysfs to see if xxx_crit_alarm xxx_lcrit_alarm xxx_max_alarm
82// xxx_min_alarm exist, then store the existing paths of the alarm attributes
83// to eventPathList.
84void checkEventLimits(
85 const std::string& sensorPathStr,
86 const boost::container::flat_map<std::string, std::vector<std::string>>&
87 limitEventMatch,
88 boost::container::flat_map<std::string, std::vector<std::string>>&
89 eventPathList)
90{
91 for (const auto& limitMatch : limitEventMatch)
92 {
93 const std::vector<std::string>& limitEventAttrs = limitMatch.second;
94 const std::string& eventName = limitMatch.first;
95 for (const auto& limitEventAttr : limitEventAttrs)
96 {
97 auto limitEventPath =
98 boost::replace_all_copy(sensorPathStr, "input", limitEventAttr);
99 std::ifstream eventFile(limitEventPath);
100 if (!eventFile.good())
101 {
102 continue;
103 }
104 eventPathList[eventName].push_back(limitEventPath);
105 }
106 }
107}
Cheng C Yang916360b2019-05-07 18:47:16 +0800108
109static void checkPWMSensor(const fs::path& sensorPath, std::string& labelHead,
110 const std::string& interfacePath,
111 sdbusplus::asio::object_server& objectServer,
112 std::string psuName)
113{
114 for (const auto& pwmName : pwmTable)
115 {
116 if (pwmName.first != labelHead)
117 {
118 continue;
119 }
120
121 const std::string& sensorPathStr = sensorPath.string();
122 const std::string& pwmPathStr =
123 boost::replace_all_copy(sensorPathStr, "input", "target");
124 std::ifstream pwmFile(pwmPathStr);
125 if (!pwmFile.good())
126 {
127 continue;
128 }
129
130 auto findPWMSensor = pwmSensors.find(psuName + labelHead);
131 if (findPWMSensor != pwmSensors.end())
132 {
133 continue;
134 }
135
136 pwmSensors[psuName + labelHead] = std::make_unique<PwmSensor>(
137 "Pwm_" + psuName + "_" + pwmName.second, pwmPathStr, objectServer,
Cheng C Yang15266a92019-06-12 08:42:52 +0800138 interfacePath + "_" + pwmName.second);
Cheng C Yang916360b2019-05-07 18:47:16 +0800139 }
140}
141
142void createSensors(boost::asio::io_service& io,
143 sdbusplus::asio::object_server& objectServer,
144 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
Cheng C Yang209ec562019-03-12 16:37:44 +0800145{
146
147 ManagedObjectType sensorConfigs;
148 bool useCache = false;
149
Cheng C Yang58b2b532019-05-31 00:19:45 +0800150 // TODO may need only modify the ones that need to be changed.
151 sensors.clear();
Cheng C Yang209ec562019-03-12 16:37:44 +0800152 for (const char* type : sensorTypes)
153 {
154 if (!getSensorConfiguration(type, dbusConnection, sensorConfigs,
155 useCache))
156 {
157 std::cerr << "error get sensor config from entity manager\n";
158 return;
159 }
160 useCache = true;
161 }
162
163 std::vector<fs::path> pmbusPaths;
164 if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
165 {
166 std::cerr << "No PSU sensors in system\n";
167 return;
168 }
169
170 boost::container::flat_set<std::string> directories;
171 for (const auto& pmbusPath : pmbusPaths)
172 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800173 boost::container::flat_map<std::string, std::vector<std::string>>
174 eventPathList;
175
176 std::ifstream nameFile(pmbusPath);
177 if (!nameFile.good())
178 {
179 std::cerr << "Failure reading " << pmbusPath << "\n";
180 continue;
181 }
182
183 std::string pmbusName;
184 std::getline(nameFile, pmbusName);
185 nameFile.close();
Vijay Khemka996bad12019-05-28 15:15:16 -0700186
187 if (std::find(pmbusNames.begin(), pmbusNames.end(), pmbusName) ==
188 pmbusNames.end())
Cheng C Yang58b2b532019-05-31 00:19:45 +0800189 {
190 continue;
191 }
192
193 const std::string* psuName;
Cheng C Yang209ec562019-03-12 16:37:44 +0800194 auto directory = pmbusPath.parent_path();
195
196 auto ret = directories.insert(directory.string());
197 if (!ret.second)
198 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800199 continue; // check if path has already been searched
Cheng C Yang209ec562019-03-12 16:37:44 +0800200 }
201
James Feistb6c0b912019-07-09 12:21:44 -0700202 fs::path device = directory / "device";
Cheng C Yang209ec562019-03-12 16:37:44 +0800203 std::string deviceName = fs::canonical(device).stem();
204 auto findHyphen = deviceName.find("-");
205 if (findHyphen == std::string::npos)
206 {
207 std::cerr << "found bad device" << deviceName << "\n";
208 continue;
209 }
210 std::string busStr = deviceName.substr(0, findHyphen);
211 std::string addrStr = deviceName.substr(findHyphen + 1);
212
213 size_t bus = 0;
214 size_t addr = 0;
215
216 try
217 {
218 bus = std::stoi(busStr);
219 addr = std::stoi(addrStr, 0, 16);
220 }
James Feistb6c0b912019-07-09 12:21:44 -0700221 catch (std::invalid_argument&)
Cheng C Yang209ec562019-03-12 16:37:44 +0800222 {
223 continue;
224 }
225
Cheng C Yang209ec562019-03-12 16:37:44 +0800226 const std::pair<std::string, boost::container::flat_map<
227 std::string, BasicVariantType>>*
228 baseConfig = nullptr;
229 const SensorData* sensorData = nullptr;
230 const std::string* interfacePath = nullptr;
231 const char* sensorType = nullptr;
232
233 for (const std::pair<sdbusplus::message::object_path, SensorData>&
234 sensor : sensorConfigs)
235 {
236 sensorData = &(sensor.second);
237 for (const char* type : sensorTypes)
238 {
239 auto sensorBase = sensorData->find(type);
240 if (sensorBase != sensorData->end())
241 {
242 baseConfig = &(*sensorBase);
243 sensorType = type;
244 break;
245 }
246 }
247 if (baseConfig == nullptr)
248 {
249 std::cerr << "error finding base configuration for "
250 << deviceName << "\n";
251 continue;
252 }
253
254 auto configBus = baseConfig->second.find("Bus");
255 auto configAddress = baseConfig->second.find("Address");
256
257 if (configBus == baseConfig->second.end() ||
258 configAddress == baseConfig->second.end())
259 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800260 std::cerr << "error finding necessary entry in configuration\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800261 continue;
262 }
263
Cheng C Yang58b2b532019-05-31 00:19:45 +0800264 const uint64_t* confBus;
265 const uint64_t* confAddr;
266 if (!(confBus = std::get_if<uint64_t>(&(configBus->second))) ||
267 !(confAddr = std::get_if<uint64_t>(&(configAddress->second))))
268 {
269 std::cerr
270 << "Canot get bus or address, invalid configuration\n";
271 continue;
272 }
273
274 if ((*confBus != bus) || (*confAddr != addr))
Cheng C Yang209ec562019-03-12 16:37:44 +0800275 {
276 continue;
277 }
278
279 interfacePath = &(sensor.first.str);
280 break;
281 }
282 if (interfacePath == nullptr)
283 {
284 std::cerr << "failed to find match for " << deviceName << "\n";
285 continue;
286 }
287
Cheng C Yange50345b2019-04-02 17:26:15 +0800288 auto findPSUName = baseConfig->second.find("Name");
289 if (findPSUName == baseConfig->second.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800290 {
291 std::cerr << "could not determine configuration name for "
292 << deviceName << "\n";
293 continue;
294 }
295
Cheng C Yang58b2b532019-05-31 00:19:45 +0800296 if (!(psuName = std::get_if<std::string>(&(findPSUName->second))))
297 {
298 std::cerr << "Cannot find psu name, invalid configuration\n";
299 continue;
300 }
301 checkEvent(directory.string(), eventMatch, eventPathList);
302
Vijay Khemka996bad12019-05-28 15:15:16 -0700303 /* Check if there are more sensors in the same interface */
304 int i = 1;
305 std::vector<std::string> psuNames;
306 do
307 {
308 psuNames.push_back(std::get<std::string>(findPSUName->second));
309 findPSUName = baseConfig->second.find("Name" + std::to_string(i++));
310 } while (findPSUName != baseConfig->second.end());
311
Cheng C Yange50345b2019-04-02 17:26:15 +0800312 std::vector<fs::path> sensorPaths;
James Feistb6c0b912019-07-09 12:21:44 -0700313 if (!findFiles(directory, R"(\w\d+_input$)", sensorPaths, 0))
Cheng C Yang209ec562019-03-12 16:37:44 +0800314 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800315 std::cerr << "No PSU non-label sensor in PSU\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800316 continue;
317 }
318
Vijay Khemka996bad12019-05-28 15:15:16 -0700319 /* Find array of labels to be exposed if it is defined in config */
320 std::vector<std::string> findLabels;
321 auto findLabelObj = baseConfig->second.find("Labels");
322 if (findLabelObj != baseConfig->second.end())
323 {
324 findLabels =
325 std::get<std::vector<std::string>>(findLabelObj->second);
326 }
327
Cheng C Yange50345b2019-04-02 17:26:15 +0800328 for (const auto& sensorPath : sensorPaths)
Cheng C Yang209ec562019-03-12 16:37:44 +0800329 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800330
Cheng C Yange50345b2019-04-02 17:26:15 +0800331 std::string labelHead;
332 std::string sensorPathStr = sensorPath.string();
333 std::string sensorNameStr = sensorPath.filename();
334 std::string sensorNameSubStr =
335 sensorNameStr.substr(0, sensorNameStr.find("_") - 1);
336
Cheng C Yangecba9de2019-09-12 23:41:50 +0800337 auto labelPath =
338 boost::replace_all_copy(sensorPathStr, "input", "label");
339 std::ifstream labelFile(labelPath);
340 if (!labelFile.good())
Cheng C Yang209ec562019-03-12 16:37:44 +0800341 {
Cheng C Yangecba9de2019-09-12 23:41:50 +0800342 std::cerr << "Failure reading " << sensorPath << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800343 labelHead = sensorNameStr.substr(0, sensorNameStr.find("_"));
Cheng C Yang209ec562019-03-12 16:37:44 +0800344 }
345 else
346 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800347 std::string label;
348 std::getline(labelFile, label);
349 labelFile.close();
Cheng C Yange50345b2019-04-02 17:26:15 +0800350 auto findSensor = sensors.find(label);
351 if (findSensor != sensors.end())
352 {
353 continue;
354 }
355
356 labelHead = label.substr(0, label.find(" "));
357 }
358
Cheng C Yang916360b2019-05-07 18:47:16 +0800359 checkPWMSensor(sensorPath, labelHead, *interfacePath, objectServer,
Vijay Khemka996bad12019-05-28 15:15:16 -0700360 psuNames[0]);
Cheng C Yang916360b2019-05-07 18:47:16 +0800361
Vijay Khemka996bad12019-05-28 15:15:16 -0700362 if (!findLabels.empty())
363 {
364 /* Check if this labelHead is enabled in config file */
365 if (std::find(findLabels.begin(), findLabels.end(),
366 labelHead) == findLabels.end())
367 {
368 continue;
369 }
370 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800371
Vijay Khemka996bad12019-05-28 15:15:16 -0700372 /* Find out sensor name index for this label */
373 uint8_t nameIndex = labelHead[labelHead.size() - 1];
374 if (nameIndex > '1' && nameIndex <= '9')
375 {
376 nameIndex -= '1';
377 if (psuNames.size() <= nameIndex)
378 {
379 continue;
380 }
381 }
382 else
James Feist17ab6e02019-06-25 12:28:13 -0700383 {
Vijay Khemka996bad12019-05-28 15:15:16 -0700384 nameIndex = 0;
James Feist17ab6e02019-06-25 12:28:13 -0700385 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800386
387 auto findProperty = labelMatch.find(labelHead);
388 if (findProperty == labelMatch.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800389 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800390 continue;
391 }
392
Cheng C Yang58b2b532019-05-31 00:19:45 +0800393 checkEventLimits(sensorPathStr, limitEventMatch, eventPathList);
394
Cheng C Yange50345b2019-04-02 17:26:15 +0800395 unsigned int factor =
396 std::pow(10, findProperty->second.sensorScaleFactor);
Vijay Khemka996bad12019-05-28 15:15:16 -0700397
Vijay Khemkadbdcfe02019-07-25 12:56:17 -0700398 /* Change first char of substring to uppercase */
399 char firstChar = sensorNameSubStr[0] - 0x20;
400 std::string strScaleFactor =
401 firstChar + sensorNameSubStr.substr(1) + "ScaleFactor";
402
403 auto findScaleFactor = baseConfig->second.find(strScaleFactor);
Vijay Khemka53ca4442019-07-23 11:03:55 -0700404 if (findScaleFactor != baseConfig->second.end())
405 {
406 factor =
407 std::visit(VariantToIntVisitor(), findScaleFactor->second);
408 }
409
Vijay Khemka996bad12019-05-28 15:15:16 -0700410 std::vector<thresholds::Threshold> sensorThresholds;
411
James Feist17ab6e02019-06-25 12:28:13 -0700412 if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
Cheng C Yange50345b2019-04-02 17:26:15 +0800413 {
James Feist17ab6e02019-06-25 12:28:13 -0700414 std::cerr << "error populating thresholds for "
415 << sensorNameSubStr << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800416 }
417
418 auto findSensorType = sensorTable.find(sensorNameSubStr);
419 if (findSensorType == sensorTable.end())
420 {
421 std::cerr << "Cannot find PSU sensorType\n";
422 continue;
423 }
424
425 std::string sensorName =
Vijay Khemka996bad12019-05-28 15:15:16 -0700426 psuNames[nameIndex] + " " + findProperty->second.labelTypeName;
Cheng C Yange50345b2019-04-02 17:26:15 +0800427
Cheng C Yang58b2b532019-05-31 00:19:45 +0800428 sensors[sensorName] = std::make_unique<PSUSensor>(
Cheng C Yange50345b2019-04-02 17:26:15 +0800429 sensorPathStr, sensorType, objectServer, dbusConnection, io,
Cheng C Yang209ec562019-03-12 16:37:44 +0800430 sensorName, std::move(sensorThresholds), *interfacePath,
Cheng C Yange50345b2019-04-02 17:26:15 +0800431 findSensorType->second, factor, findProperty->second.maxReading,
432 findProperty->second.minReading);
Cheng C Yang209ec562019-03-12 16:37:44 +0800433 }
Cheng C Yang58b2b532019-05-31 00:19:45 +0800434
435 // OperationalStatus event
436 combineEvents[*psuName + "OperationalStatus"] =
437 std::make_unique<PSUCombineEvent>(
438 objectServer, io, *psuName, eventPathList, "OperationalStatus");
Cheng C Yang209ec562019-03-12 16:37:44 +0800439 }
440 return;
441}
442
Cheng C Yang916360b2019-05-07 18:47:16 +0800443void propertyInitialize(void)
Cheng C Yang209ec562019-03-12 16:37:44 +0800444{
Cheng C Yange50345b2019-04-02 17:26:15 +0800445 sensorTable = {{"power", "power/"},
446 {"curr", "current/"},
447 {"temp", "temperature/"},
448 {"in", "voltage/"},
449 {"fan", "fan_tach/"}};
450
451 labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
452 {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700453 {"pout2", PSUProperty("Output Power", 3000, 0, 6)},
454 {"pout3", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700455 {"power1", PSUProperty("Output Power", 3000, 0, 6)},
Cheng C Yangbdbde962019-04-26 22:50:34 +0800456 {"vin", PSUProperty("Input Voltage", 300, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700457 {"vout1", PSUProperty("Output Voltage", 255, 0, 3)},
458 {"vout2", PSUProperty("Output Voltage", 255, 0, 3)},
459 {"vout3", PSUProperty("Output Voltage", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700460 {"in1", PSUProperty("Output Voltage", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800461 {"iin", PSUProperty("Input Current", 20, 0, 3)},
462 {"iout1", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700463 {"iout2", PSUProperty("Output Current", 255, 0, 3)},
464 {"iout3", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700465 {"curr1", PSUProperty("Output Current", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800466 {"temp1", PSUProperty("Temperature", 127, -128, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700467 {"temp2", PSUProperty("Temperature", 127, -128, 3)},
468 {"temp3", PSUProperty("Temperature", 127, -128, 3)},
Cheng C Yang8dbb3952019-05-23 00:03:12 +0800469 {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0)},
470 {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0)}};
Cheng C Yang916360b2019-05-07 18:47:16 +0800471
472 pwmTable = {{"fan1", "Fan_1"}, {"fan2", "Fan_2"}};
Cheng C Yang58b2b532019-05-31 00:19:45 +0800473
474 limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
475 {"Failure", {"crit_alarm", "lcrit_alarm"}}};
476
477 eventMatch = {
478 {"PredictiveFailure", {"power1_alarm"}},
479 {"Failure", {"in2_alarm"}},
Cheng C Yang9c45e6b2019-08-13 07:21:32 +0800480 {"ACLost", {"in1_beep"}},
481 {"FanFault", {"fan1_alarm", "fan2_alarm", "fan1_fault", "fan2_fault"}},
482 {"ConfigureError", {"in1_fault"}}};
Cheng C Yang209ec562019-03-12 16:37:44 +0800483}
484
James Feistb6c0b912019-07-09 12:21:44 -0700485int main()
Cheng C Yang209ec562019-03-12 16:37:44 +0800486{
487 boost::asio::io_service io;
488 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
489
490 systemBus->request_name("xyz.openbmc_project.PSUSensor");
491 sdbusplus::asio::object_server objectServer(systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800492 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
Cheng C Yang209ec562019-03-12 16:37:44 +0800493
Cheng C Yang916360b2019-05-07 18:47:16 +0800494 propertyInitialize();
Cheng C Yang209ec562019-03-12 16:37:44 +0800495
Cheng C Yang916360b2019-05-07 18:47:16 +0800496 io.post([&]() { createSensors(io, objectServer, systemBus); });
Cheng C Yang209ec562019-03-12 16:37:44 +0800497 boost::asio::deadline_timer filterTimer(io);
498 std::function<void(sdbusplus::message::message&)> eventHandler =
499 [&](sdbusplus::message::message& message) {
500 if (message.is_method_error())
501 {
502 std::cerr << "callback method error\n";
503 return;
504 }
505 filterTimer.expires_from_now(boost::posix_time::seconds(1));
506 filterTimer.async_wait([&](const boost::system::error_code& ec) {
507 if (ec == boost::asio::error::operation_aborted)
508 {
509 return;
510 }
511 else if (ec)
512 {
513 std::cerr << "timer error\n";
514 }
Cheng C Yang916360b2019-05-07 18:47:16 +0800515 createSensors(io, objectServer, systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800516 });
517 };
518
519 for (const char* type : sensorTypes)
520 {
521 auto match = std::make_unique<sdbusplus::bus::match::match>(
522 static_cast<sdbusplus::bus::bus&>(*systemBus),
523 "type='signal',member='PropertiesChanged',path_namespace='" +
524 std::string(inventoryPath) + "',arg0namespace='" + type + "'",
525 eventHandler);
526 matches.emplace_back(std::move(match));
527 }
528 io.run();
529}