blob: c3097e7911c4ee3b244e439f7e31f5f4ede7d885 [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
337 std::string labelPathStr =
338 boost::replace_all_copy(sensorNameStr, "input", "label");
339 std::vector<fs::path> labelPaths;
James Feistb6c0b912019-07-09 12:21:44 -0700340 if (!findFiles(directory, labelPathStr, labelPaths, 0))
Cheng C Yang209ec562019-03-12 16:37:44 +0800341 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800342 std::cerr << "No PSU non-label sensor in PSU\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800343 continue;
344 }
345
Cheng C Yange50345b2019-04-02 17:26:15 +0800346 if (labelPaths.empty())
Cheng C Yang209ec562019-03-12 16:37:44 +0800347 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800348 labelHead = sensorNameStr.substr(0, sensorNameStr.find("_"));
Cheng C Yang209ec562019-03-12 16:37:44 +0800349 }
350 else
351 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800352 auto labelPath =
353 boost::replace_all_copy(sensorPathStr, "input", "label");
354 std::ifstream labelFile(labelPath);
355 if (!labelFile.good())
356 {
357 std::cerr << "Failure reading " << sensorPath << "\n";
358 continue;
359 }
360 std::string label;
361 std::getline(labelFile, label);
362 labelFile.close();
Cheng C Yang209ec562019-03-12 16:37:44 +0800363
Cheng C Yange50345b2019-04-02 17:26:15 +0800364 auto findSensor = sensors.find(label);
365 if (findSensor != sensors.end())
366 {
367 continue;
368 }
369
370 labelHead = label.substr(0, label.find(" "));
371 }
372
Cheng C Yang916360b2019-05-07 18:47:16 +0800373 checkPWMSensor(sensorPath, labelHead, *interfacePath, objectServer,
Vijay Khemka996bad12019-05-28 15:15:16 -0700374 psuNames[0]);
Cheng C Yang916360b2019-05-07 18:47:16 +0800375
Vijay Khemka996bad12019-05-28 15:15:16 -0700376 if (!findLabels.empty())
377 {
378 /* Check if this labelHead is enabled in config file */
379 if (std::find(findLabels.begin(), findLabels.end(),
380 labelHead) == findLabels.end())
381 {
382 continue;
383 }
384 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800385
Vijay Khemka996bad12019-05-28 15:15:16 -0700386 /* Find out sensor name index for this label */
387 uint8_t nameIndex = labelHead[labelHead.size() - 1];
388 if (nameIndex > '1' && nameIndex <= '9')
389 {
390 nameIndex -= '1';
391 if (psuNames.size() <= nameIndex)
392 {
393 continue;
394 }
395 }
396 else
James Feist17ab6e02019-06-25 12:28:13 -0700397 {
Vijay Khemka996bad12019-05-28 15:15:16 -0700398 nameIndex = 0;
James Feist17ab6e02019-06-25 12:28:13 -0700399 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800400
401 auto findProperty = labelMatch.find(labelHead);
402 if (findProperty == labelMatch.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800403 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800404 continue;
405 }
406
Cheng C Yang58b2b532019-05-31 00:19:45 +0800407 checkEventLimits(sensorPathStr, limitEventMatch, eventPathList);
408
Cheng C Yange50345b2019-04-02 17:26:15 +0800409 unsigned int factor =
410 std::pow(10, findProperty->second.sensorScaleFactor);
Vijay Khemka996bad12019-05-28 15:15:16 -0700411
Vijay Khemkadbdcfe02019-07-25 12:56:17 -0700412 /* Change first char of substring to uppercase */
413 char firstChar = sensorNameSubStr[0] - 0x20;
414 std::string strScaleFactor =
415 firstChar + sensorNameSubStr.substr(1) + "ScaleFactor";
416
417 auto findScaleFactor = baseConfig->second.find(strScaleFactor);
Vijay Khemka53ca4442019-07-23 11:03:55 -0700418 if (findScaleFactor != baseConfig->second.end())
419 {
420 factor =
421 std::visit(VariantToIntVisitor(), findScaleFactor->second);
422 }
423
Vijay Khemka996bad12019-05-28 15:15:16 -0700424 std::vector<thresholds::Threshold> sensorThresholds;
425
James Feist17ab6e02019-06-25 12:28:13 -0700426 if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
Cheng C Yange50345b2019-04-02 17:26:15 +0800427 {
James Feist17ab6e02019-06-25 12:28:13 -0700428 std::cerr << "error populating thresholds for "
429 << sensorNameSubStr << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800430 }
431
432 auto findSensorType = sensorTable.find(sensorNameSubStr);
433 if (findSensorType == sensorTable.end())
434 {
435 std::cerr << "Cannot find PSU sensorType\n";
436 continue;
437 }
438
439 std::string sensorName =
Vijay Khemka996bad12019-05-28 15:15:16 -0700440 psuNames[nameIndex] + " " + findProperty->second.labelTypeName;
Cheng C Yange50345b2019-04-02 17:26:15 +0800441
Cheng C Yang58b2b532019-05-31 00:19:45 +0800442 sensors[sensorName] = std::make_unique<PSUSensor>(
Cheng C Yange50345b2019-04-02 17:26:15 +0800443 sensorPathStr, sensorType, objectServer, dbusConnection, io,
Cheng C Yang209ec562019-03-12 16:37:44 +0800444 sensorName, std::move(sensorThresholds), *interfacePath,
Cheng C Yange50345b2019-04-02 17:26:15 +0800445 findSensorType->second, factor, findProperty->second.maxReading,
446 findProperty->second.minReading);
Cheng C Yang209ec562019-03-12 16:37:44 +0800447 }
Cheng C Yang58b2b532019-05-31 00:19:45 +0800448
449 // OperationalStatus event
450 combineEvents[*psuName + "OperationalStatus"] =
451 std::make_unique<PSUCombineEvent>(
452 objectServer, io, *psuName, eventPathList, "OperationalStatus");
Cheng C Yang209ec562019-03-12 16:37:44 +0800453 }
454 return;
455}
456
Cheng C Yang916360b2019-05-07 18:47:16 +0800457void propertyInitialize(void)
Cheng C Yang209ec562019-03-12 16:37:44 +0800458{
Cheng C Yange50345b2019-04-02 17:26:15 +0800459 sensorTable = {{"power", "power/"},
460 {"curr", "current/"},
461 {"temp", "temperature/"},
462 {"in", "voltage/"},
463 {"fan", "fan_tach/"}};
464
465 labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
466 {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700467 {"pout2", PSUProperty("Output Power", 3000, 0, 6)},
468 {"pout3", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700469 {"power1", PSUProperty("Output Power", 3000, 0, 6)},
Cheng C Yangbdbde962019-04-26 22:50:34 +0800470 {"vin", PSUProperty("Input Voltage", 300, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700471 {"vout1", PSUProperty("Output Voltage", 255, 0, 3)},
472 {"vout2", PSUProperty("Output Voltage", 255, 0, 3)},
473 {"vout3", PSUProperty("Output Voltage", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700474 {"in1", PSUProperty("Output Voltage", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800475 {"iin", PSUProperty("Input Current", 20, 0, 3)},
476 {"iout1", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700477 {"iout2", PSUProperty("Output Current", 255, 0, 3)},
478 {"iout3", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700479 {"curr1", PSUProperty("Output Current", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800480 {"temp1", PSUProperty("Temperature", 127, -128, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700481 {"temp2", PSUProperty("Temperature", 127, -128, 3)},
482 {"temp3", PSUProperty("Temperature", 127, -128, 3)},
Cheng C Yang8dbb3952019-05-23 00:03:12 +0800483 {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0)},
484 {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0)}};
Cheng C Yang916360b2019-05-07 18:47:16 +0800485
486 pwmTable = {{"fan1", "Fan_1"}, {"fan2", "Fan_2"}};
Cheng C Yang58b2b532019-05-31 00:19:45 +0800487
488 limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
489 {"Failure", {"crit_alarm", "lcrit_alarm"}}};
490
491 eventMatch = {
492 {"PredictiveFailure", {"power1_alarm"}},
493 {"Failure", {"in2_alarm"}},
Cheng C Yang9c45e6b2019-08-13 07:21:32 +0800494 {"ACLost", {"in1_beep"}},
495 {"FanFault", {"fan1_alarm", "fan2_alarm", "fan1_fault", "fan2_fault"}},
496 {"ConfigureError", {"in1_fault"}}};
Cheng C Yang209ec562019-03-12 16:37:44 +0800497}
498
James Feistb6c0b912019-07-09 12:21:44 -0700499int main()
Cheng C Yang209ec562019-03-12 16:37:44 +0800500{
501 boost::asio::io_service io;
502 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
503
504 systemBus->request_name("xyz.openbmc_project.PSUSensor");
505 sdbusplus::asio::object_server objectServer(systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800506 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
Cheng C Yang209ec562019-03-12 16:37:44 +0800507
Cheng C Yang916360b2019-05-07 18:47:16 +0800508 propertyInitialize();
Cheng C Yang209ec562019-03-12 16:37:44 +0800509
Cheng C Yang916360b2019-05-07 18:47:16 +0800510 io.post([&]() { createSensors(io, objectServer, systemBus); });
Cheng C Yang209ec562019-03-12 16:37:44 +0800511 boost::asio::deadline_timer filterTimer(io);
512 std::function<void(sdbusplus::message::message&)> eventHandler =
513 [&](sdbusplus::message::message& message) {
514 if (message.is_method_error())
515 {
516 std::cerr << "callback method error\n";
517 return;
518 }
519 filterTimer.expires_from_now(boost::posix_time::seconds(1));
520 filterTimer.async_wait([&](const boost::system::error_code& ec) {
521 if (ec == boost::asio::error::operation_aborted)
522 {
523 return;
524 }
525 else if (ec)
526 {
527 std::cerr << "timer error\n";
528 }
Cheng C Yang916360b2019-05-07 18:47:16 +0800529 createSensors(io, objectServer, systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800530 });
531 };
532
533 for (const char* type : sensorTypes)
534 {
535 auto match = std::make_unique<sdbusplus::bus::match::match>(
536 static_cast<sdbusplus::bus::bus&>(*systemBus),
537 "type='signal',member='PropertiesChanged',path_namespace='" +
538 std::string(inventoryPath) + "',arg0namespace='" + type + "'",
539 eventHandler);
540 matches.emplace_back(std::move(match));
541 }
542 io.run();
543}