blob: 400c514048b4bbbefb1f51098d8bfbd43e199b2e [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 Yang92498eb2019-09-26 21:59:25 +0800152 combineEvents.clear();
Cheng C Yang209ec562019-03-12 16:37:44 +0800153 for (const char* type : sensorTypes)
154 {
155 if (!getSensorConfiguration(type, dbusConnection, sensorConfigs,
156 useCache))
157 {
158 std::cerr << "error get sensor config from entity manager\n";
159 return;
160 }
161 useCache = true;
162 }
163
164 std::vector<fs::path> pmbusPaths;
165 if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
166 {
167 std::cerr << "No PSU sensors in system\n";
168 return;
169 }
170
171 boost::container::flat_set<std::string> directories;
172 for (const auto& pmbusPath : pmbusPaths)
173 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800174 boost::container::flat_map<std::string, std::vector<std::string>>
175 eventPathList;
176
177 std::ifstream nameFile(pmbusPath);
178 if (!nameFile.good())
179 {
180 std::cerr << "Failure reading " << pmbusPath << "\n";
181 continue;
182 }
183
184 std::string pmbusName;
185 std::getline(nameFile, pmbusName);
186 nameFile.close();
Vijay Khemka996bad12019-05-28 15:15:16 -0700187
188 if (std::find(pmbusNames.begin(), pmbusNames.end(), pmbusName) ==
189 pmbusNames.end())
Cheng C Yang58b2b532019-05-31 00:19:45 +0800190 {
191 continue;
192 }
193
194 const std::string* psuName;
Cheng C Yang209ec562019-03-12 16:37:44 +0800195 auto directory = pmbusPath.parent_path();
196
197 auto ret = directories.insert(directory.string());
198 if (!ret.second)
199 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800200 continue; // check if path has already been searched
Cheng C Yang209ec562019-03-12 16:37:44 +0800201 }
202
James Feistb6c0b912019-07-09 12:21:44 -0700203 fs::path device = directory / "device";
Cheng C Yang209ec562019-03-12 16:37:44 +0800204 std::string deviceName = fs::canonical(device).stem();
205 auto findHyphen = deviceName.find("-");
206 if (findHyphen == std::string::npos)
207 {
208 std::cerr << "found bad device" << deviceName << "\n";
209 continue;
210 }
211 std::string busStr = deviceName.substr(0, findHyphen);
212 std::string addrStr = deviceName.substr(findHyphen + 1);
213
214 size_t bus = 0;
215 size_t addr = 0;
216
217 try
218 {
219 bus = std::stoi(busStr);
220 addr = std::stoi(addrStr, 0, 16);
221 }
James Feistb6c0b912019-07-09 12:21:44 -0700222 catch (std::invalid_argument&)
Cheng C Yang209ec562019-03-12 16:37:44 +0800223 {
224 continue;
225 }
226
Cheng C Yang209ec562019-03-12 16:37:44 +0800227 const std::pair<std::string, boost::container::flat_map<
228 std::string, BasicVariantType>>*
229 baseConfig = nullptr;
230 const SensorData* sensorData = nullptr;
231 const std::string* interfacePath = nullptr;
232 const char* sensorType = nullptr;
233
234 for (const std::pair<sdbusplus::message::object_path, SensorData>&
235 sensor : sensorConfigs)
236 {
237 sensorData = &(sensor.second);
238 for (const char* type : sensorTypes)
239 {
240 auto sensorBase = sensorData->find(type);
241 if (sensorBase != sensorData->end())
242 {
243 baseConfig = &(*sensorBase);
244 sensorType = type;
245 break;
246 }
247 }
248 if (baseConfig == nullptr)
249 {
250 std::cerr << "error finding base configuration for "
251 << deviceName << "\n";
252 continue;
253 }
254
255 auto configBus = baseConfig->second.find("Bus");
256 auto configAddress = baseConfig->second.find("Address");
257
258 if (configBus == baseConfig->second.end() ||
259 configAddress == baseConfig->second.end())
260 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800261 std::cerr << "error finding necessary entry in configuration\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800262 continue;
263 }
264
Cheng C Yang58b2b532019-05-31 00:19:45 +0800265 const uint64_t* confBus;
266 const uint64_t* confAddr;
267 if (!(confBus = std::get_if<uint64_t>(&(configBus->second))) ||
268 !(confAddr = std::get_if<uint64_t>(&(configAddress->second))))
269 {
270 std::cerr
271 << "Canot get bus or address, invalid configuration\n";
272 continue;
273 }
274
275 if ((*confBus != bus) || (*confAddr != addr))
Cheng C Yang209ec562019-03-12 16:37:44 +0800276 {
277 continue;
278 }
279
280 interfacePath = &(sensor.first.str);
281 break;
282 }
283 if (interfacePath == nullptr)
284 {
285 std::cerr << "failed to find match for " << deviceName << "\n";
286 continue;
287 }
288
Cheng C Yange50345b2019-04-02 17:26:15 +0800289 auto findPSUName = baseConfig->second.find("Name");
290 if (findPSUName == baseConfig->second.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800291 {
292 std::cerr << "could not determine configuration name for "
293 << deviceName << "\n";
294 continue;
295 }
296
Cheng C Yang58b2b532019-05-31 00:19:45 +0800297 if (!(psuName = std::get_if<std::string>(&(findPSUName->second))))
298 {
299 std::cerr << "Cannot find psu name, invalid configuration\n";
300 continue;
301 }
302 checkEvent(directory.string(), eventMatch, eventPathList);
303
Vijay Khemka996bad12019-05-28 15:15:16 -0700304 /* Check if there are more sensors in the same interface */
305 int i = 1;
306 std::vector<std::string> psuNames;
307 do
308 {
309 psuNames.push_back(std::get<std::string>(findPSUName->second));
310 findPSUName = baseConfig->second.find("Name" + std::to_string(i++));
311 } while (findPSUName != baseConfig->second.end());
312
Cheng C Yange50345b2019-04-02 17:26:15 +0800313 std::vector<fs::path> sensorPaths;
James Feistb6c0b912019-07-09 12:21:44 -0700314 if (!findFiles(directory, R"(\w\d+_input$)", sensorPaths, 0))
Cheng C Yang209ec562019-03-12 16:37:44 +0800315 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800316 std::cerr << "No PSU non-label sensor in PSU\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800317 continue;
318 }
319
Vijay Khemka996bad12019-05-28 15:15:16 -0700320 /* Find array of labels to be exposed if it is defined in config */
321 std::vector<std::string> findLabels;
322 auto findLabelObj = baseConfig->second.find("Labels");
323 if (findLabelObj != baseConfig->second.end())
324 {
325 findLabels =
326 std::get<std::vector<std::string>>(findLabelObj->second);
327 }
328
Cheng C Yange50345b2019-04-02 17:26:15 +0800329 for (const auto& sensorPath : sensorPaths)
Cheng C Yang209ec562019-03-12 16:37:44 +0800330 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800331
Cheng C Yange50345b2019-04-02 17:26:15 +0800332 std::string labelHead;
333 std::string sensorPathStr = sensorPath.string();
334 std::string sensorNameStr = sensorPath.filename();
335 std::string sensorNameSubStr =
336 sensorNameStr.substr(0, sensorNameStr.find("_") - 1);
337
Cheng C Yangecba9de2019-09-12 23:41:50 +0800338 auto labelPath =
339 boost::replace_all_copy(sensorPathStr, "input", "label");
340 std::ifstream labelFile(labelPath);
341 if (!labelFile.good())
Cheng C Yang209ec562019-03-12 16:37:44 +0800342 {
Cheng C Yangecba9de2019-09-12 23:41:50 +0800343 std::cerr << "Failure reading " << sensorPath << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800344 labelHead = sensorNameStr.substr(0, sensorNameStr.find("_"));
Cheng C Yang209ec562019-03-12 16:37:44 +0800345 }
346 else
347 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800348 std::string label;
349 std::getline(labelFile, label);
350 labelFile.close();
Cheng C Yange50345b2019-04-02 17:26:15 +0800351 auto findSensor = sensors.find(label);
352 if (findSensor != sensors.end())
353 {
354 continue;
355 }
356
357 labelHead = label.substr(0, label.find(" "));
358 }
359
Cheng C Yang916360b2019-05-07 18:47:16 +0800360 checkPWMSensor(sensorPath, labelHead, *interfacePath, objectServer,
Vijay Khemka996bad12019-05-28 15:15:16 -0700361 psuNames[0]);
Cheng C Yang916360b2019-05-07 18:47:16 +0800362
Vijay Khemka996bad12019-05-28 15:15:16 -0700363 if (!findLabels.empty())
364 {
365 /* Check if this labelHead is enabled in config file */
366 if (std::find(findLabels.begin(), findLabels.end(),
367 labelHead) == findLabels.end())
368 {
369 continue;
370 }
371 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800372
Vijay Khemka996bad12019-05-28 15:15:16 -0700373 /* Find out sensor name index for this label */
374 uint8_t nameIndex = labelHead[labelHead.size() - 1];
375 if (nameIndex > '1' && nameIndex <= '9')
376 {
377 nameIndex -= '1';
378 if (psuNames.size() <= nameIndex)
379 {
380 continue;
381 }
382 }
383 else
James Feist17ab6e02019-06-25 12:28:13 -0700384 {
Vijay Khemka996bad12019-05-28 15:15:16 -0700385 nameIndex = 0;
James Feist17ab6e02019-06-25 12:28:13 -0700386 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800387
388 auto findProperty = labelMatch.find(labelHead);
389 if (findProperty == labelMatch.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800390 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800391 continue;
392 }
393
Cheng C Yang58b2b532019-05-31 00:19:45 +0800394 checkEventLimits(sensorPathStr, limitEventMatch, eventPathList);
395
Cheng C Yange50345b2019-04-02 17:26:15 +0800396 unsigned int factor =
397 std::pow(10, findProperty->second.sensorScaleFactor);
Vijay Khemka996bad12019-05-28 15:15:16 -0700398
Vijay Khemkadbdcfe02019-07-25 12:56:17 -0700399 /* Change first char of substring to uppercase */
400 char firstChar = sensorNameSubStr[0] - 0x20;
401 std::string strScaleFactor =
402 firstChar + sensorNameSubStr.substr(1) + "ScaleFactor";
403
404 auto findScaleFactor = baseConfig->second.find(strScaleFactor);
Vijay Khemka53ca4442019-07-23 11:03:55 -0700405 if (findScaleFactor != baseConfig->second.end())
406 {
407 factor =
408 std::visit(VariantToIntVisitor(), findScaleFactor->second);
409 }
410
Vijay Khemka996bad12019-05-28 15:15:16 -0700411 std::vector<thresholds::Threshold> sensorThresholds;
412
James Feist17ab6e02019-06-25 12:28:13 -0700413 if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
Cheng C Yange50345b2019-04-02 17:26:15 +0800414 {
James Feist17ab6e02019-06-25 12:28:13 -0700415 std::cerr << "error populating thresholds for "
416 << sensorNameSubStr << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800417 }
418
419 auto findSensorType = sensorTable.find(sensorNameSubStr);
420 if (findSensorType == sensorTable.end())
421 {
422 std::cerr << "Cannot find PSU sensorType\n";
423 continue;
424 }
425
426 std::string sensorName =
Vijay Khemka996bad12019-05-28 15:15:16 -0700427 psuNames[nameIndex] + " " + findProperty->second.labelTypeName;
Cheng C Yange50345b2019-04-02 17:26:15 +0800428
Cheng C Yang58b2b532019-05-31 00:19:45 +0800429 sensors[sensorName] = std::make_unique<PSUSensor>(
Cheng C Yange50345b2019-04-02 17:26:15 +0800430 sensorPathStr, sensorType, objectServer, dbusConnection, io,
Cheng C Yang209ec562019-03-12 16:37:44 +0800431 sensorName, std::move(sensorThresholds), *interfacePath,
Cheng C Yange50345b2019-04-02 17:26:15 +0800432 findSensorType->second, factor, findProperty->second.maxReading,
433 findProperty->second.minReading);
Cheng C Yang209ec562019-03-12 16:37:44 +0800434 }
Cheng C Yang58b2b532019-05-31 00:19:45 +0800435
436 // OperationalStatus event
Cheng C Yang92498eb2019-09-26 21:59:25 +0800437 combineEvents[*psuName + "OperationalStatus"] = nullptr;
Cheng C Yang58b2b532019-05-31 00:19:45 +0800438 combineEvents[*psuName + "OperationalStatus"] =
439 std::make_unique<PSUCombineEvent>(
440 objectServer, io, *psuName, eventPathList, "OperationalStatus");
Cheng C Yang209ec562019-03-12 16:37:44 +0800441 }
442 return;
443}
444
Cheng C Yang916360b2019-05-07 18:47:16 +0800445void propertyInitialize(void)
Cheng C Yang209ec562019-03-12 16:37:44 +0800446{
Cheng C Yange50345b2019-04-02 17:26:15 +0800447 sensorTable = {{"power", "power/"},
448 {"curr", "current/"},
449 {"temp", "temperature/"},
450 {"in", "voltage/"},
451 {"fan", "fan_tach/"}};
452
453 labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
454 {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700455 {"pout2", PSUProperty("Output Power", 3000, 0, 6)},
456 {"pout3", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700457 {"power1", PSUProperty("Output Power", 3000, 0, 6)},
Cheng C Yangbdbde962019-04-26 22:50:34 +0800458 {"vin", PSUProperty("Input Voltage", 300, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700459 {"vout1", PSUProperty("Output Voltage", 255, 0, 3)},
460 {"vout2", PSUProperty("Output Voltage", 255, 0, 3)},
461 {"vout3", PSUProperty("Output Voltage", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700462 {"in1", PSUProperty("Output Voltage", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800463 {"iin", PSUProperty("Input Current", 20, 0, 3)},
464 {"iout1", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700465 {"iout2", PSUProperty("Output Current", 255, 0, 3)},
466 {"iout3", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700467 {"curr1", PSUProperty("Output Current", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800468 {"temp1", PSUProperty("Temperature", 127, -128, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700469 {"temp2", PSUProperty("Temperature", 127, -128, 3)},
470 {"temp3", PSUProperty("Temperature", 127, -128, 3)},
Cheng C Yang8dbb3952019-05-23 00:03:12 +0800471 {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0)},
472 {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0)}};
Cheng C Yang916360b2019-05-07 18:47:16 +0800473
474 pwmTable = {{"fan1", "Fan_1"}, {"fan2", "Fan_2"}};
Cheng C Yang58b2b532019-05-31 00:19:45 +0800475
476 limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
477 {"Failure", {"crit_alarm", "lcrit_alarm"}}};
478
479 eventMatch = {
480 {"PredictiveFailure", {"power1_alarm"}},
481 {"Failure", {"in2_alarm"}},
Cheng C Yang9c45e6b2019-08-13 07:21:32 +0800482 {"ACLost", {"in1_beep"}},
483 {"FanFault", {"fan1_alarm", "fan2_alarm", "fan1_fault", "fan2_fault"}},
484 {"ConfigureError", {"in1_fault"}}};
Cheng C Yang209ec562019-03-12 16:37:44 +0800485}
486
James Feistb6c0b912019-07-09 12:21:44 -0700487int main()
Cheng C Yang209ec562019-03-12 16:37:44 +0800488{
489 boost::asio::io_service io;
490 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
491
492 systemBus->request_name("xyz.openbmc_project.PSUSensor");
493 sdbusplus::asio::object_server objectServer(systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800494 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
Cheng C Yang209ec562019-03-12 16:37:44 +0800495
Cheng C Yang916360b2019-05-07 18:47:16 +0800496 propertyInitialize();
Cheng C Yang209ec562019-03-12 16:37:44 +0800497
Cheng C Yang916360b2019-05-07 18:47:16 +0800498 io.post([&]() { createSensors(io, objectServer, systemBus); });
Cheng C Yang209ec562019-03-12 16:37:44 +0800499 boost::asio::deadline_timer filterTimer(io);
500 std::function<void(sdbusplus::message::message&)> eventHandler =
501 [&](sdbusplus::message::message& message) {
502 if (message.is_method_error())
503 {
504 std::cerr << "callback method error\n";
505 return;
506 }
507 filterTimer.expires_from_now(boost::posix_time::seconds(1));
508 filterTimer.async_wait([&](const boost::system::error_code& ec) {
509 if (ec == boost::asio::error::operation_aborted)
510 {
511 return;
512 }
513 else if (ec)
514 {
515 std::cerr << "timer error\n";
516 }
Cheng C Yang916360b2019-05-07 18:47:16 +0800517 createSensors(io, objectServer, systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800518 });
519 };
520
521 for (const char* type : sensorTypes)
522 {
523 auto match = std::make_unique<sdbusplus::bus::match::match>(
524 static_cast<sdbusplus::bus::bus&>(*systemBus),
525 "type='signal',member='PropertiesChanged',path_namespace='" +
526 std::string(inventoryPath) + "',arg0namespace='" + type + "'",
527 eventHandler);
528 matches.emplace_back(std::move(match));
529 }
530 io.run();
531}