1 #pragma once 2 3 #include "dbus_types.hpp" 4 #include "dbus_watcher.hpp" 5 6 #include <phosphor-logging/lg2.hpp> 7 #include <sdbusplus/bus.hpp> 8 #include <sdbusplus/bus/match.hpp> 9 10 #include <expected> 11 #include <filesystem> 12 #include <fstream> 13 #include <unordered_map> 14 15 namespace openpower 16 { 17 namespace pels 18 { 19 20 /** 21 * @class DataInterface 22 * 23 * A base class for gathering data about the system for use 24 * in PELs. Implemented this way to facilitate mocking. 25 */ 26 class DataInterfaceBase 27 { 28 public: 29 DataInterfaceBase() = default; 30 virtual ~DataInterfaceBase() = default; 31 DataInterfaceBase(const DataInterfaceBase&) = default; 32 DataInterfaceBase& operator=(const DataInterfaceBase&) = default; 33 DataInterfaceBase(DataInterfaceBase&&) = default; 34 DataInterfaceBase& operator=(DataInterfaceBase&&) = default; 35 36 /** 37 * @brief Returns the machine Type/Model 38 * 39 * @return string - The machine Type/Model string 40 */ 41 virtual std::string getMachineTypeModel() const = 0; 42 43 /** 44 * @brief Returns the machine serial number 45 * 46 * @return string - The machine serial number 47 */ 48 virtual std::string getMachineSerialNumber() const = 0; 49 50 /** 51 * @brief Says if the system is managed by a hardware 52 * management console. 53 * @return bool - If the system is HMC managed 54 */ 55 virtual bool isHMCManaged() const 56 { 57 return _hmcManaged; 58 } 59 60 /** 61 * @brief Says if the host is up and running 62 * 63 * @return bool - If the host is running 64 */ 65 virtual bool isHostUp() const 66 { 67 return _hostUp; 68 } 69 70 using HostStateChangeFunc = std::function<void(bool)>; 71 72 /** 73 * @brief Register a callback function that will get 74 * called on all host on/off transitions. 75 * 76 * The void(bool) function will get passed the new 77 * value of the host state. 78 * 79 * @param[in] name - The subscription name 80 * @param[in] func - The function to run 81 */ 82 void subscribeToHostStateChange(const std::string& name, 83 HostStateChangeFunc func) 84 { 85 _hostChangeCallbacks[name] = func; 86 } 87 88 /** 89 * @brief Unsubscribe from host state changes. 90 * 91 * @param[in] name - The subscription name 92 */ 93 void unsubscribeFromHostStateChange(const std::string& name) 94 { 95 _hostChangeCallbacks.erase(name); 96 } 97 98 using FRUPresentFunc = 99 std::function<void(const std::string& /* locationCode */)>; 100 101 /** 102 * @brief Register a callback function that will get 103 * called when certain FRUs become present. 104 * 105 * The void(std::string) function will get passed the 106 * location code of the FRU. 107 * 108 * @param[in] name - The subscription name 109 * @param[in] func - The function to run 110 */ 111 void subscribeToFruPresent(const std::string& name, FRUPresentFunc func) 112 { 113 _fruPresentCallbacks[name] = std::move(func); 114 } 115 116 /** 117 * @brief Returns the BMC firmware version 118 * 119 * @return std::string - The BMC version 120 */ 121 virtual std::string getBMCFWVersion() const 122 { 123 return _bmcFWVersion; 124 } 125 126 /** 127 * @brief Returns the server firmware version 128 * 129 * @return std::string - The server firmware version 130 */ 131 virtual std::string getServerFWVersion() const 132 { 133 return _serverFWVersion; 134 } 135 136 /** 137 * @brief Returns the BMC FW version ID 138 * 139 * @return std::string - The BMC FW version ID 140 */ 141 virtual std::string getBMCFWVersionID() const 142 { 143 return _bmcFWVersionID; 144 } 145 146 /** 147 * @brief Returns the process name given its PID. 148 * 149 * @param[in] pid - The PID value as a string 150 * 151 * @return std::optional<std::string> - The name, or std::nullopt 152 */ 153 std::optional<std::string> getProcessName(const std::string& pid) const 154 { 155 namespace fs = std::filesystem; 156 157 fs::path path{"/proc"}; 158 path /= fs::path{pid} / "exe"; 159 160 if (fs::exists(path)) 161 { 162 return fs::read_symlink(path); 163 } 164 165 return std::nullopt; 166 } 167 168 /** 169 * @brief Returns the time the system was running. 170 * 171 * @return std::optional<uint64_t> - The System uptime or std::nullopt 172 */ 173 std::optional<uint64_t> getUptimeInSeconds() const 174 { 175 std::ifstream versionFile{"/proc/uptime"}; 176 std::string line{}; 177 178 std::getline(versionFile, line); 179 auto pos = line.find(" "); 180 if (pos == std::string::npos) 181 { 182 return std::nullopt; 183 } 184 185 uint64_t seconds = atol(line.substr(0, pos).c_str()); 186 if (seconds == 0) 187 { 188 return std::nullopt; 189 } 190 191 return seconds; 192 } 193 194 /** 195 * @brief Returns the time the system was running. 196 * 197 * @param[in] seconds - The number of seconds the system has been running 198 * 199 * @return std::string - days/hours/minutes/seconds 200 */ 201 std::string getBMCUptime(uint64_t seconds) const 202 { 203 time_t t(seconds); 204 tm* p = gmtime(&t); 205 206 std::string uptime = 207 std::to_string(p->tm_year - 70) + "y " + 208 std::to_string(p->tm_yday) + "d " + std::to_string(p->tm_hour) + 209 "h " + std::to_string(p->tm_min) + "m " + 210 std::to_string(p->tm_sec) + "s"; 211 212 return uptime; 213 } 214 215 /** 216 * @brief Returns the system load average over the past 1 minute, 5 minutes 217 * and 15 minutes. 218 * 219 * @return std::string - The system load average 220 */ 221 std::string getBMCLoadAvg() const 222 { 223 std::string loadavg{}; 224 225 std::ifstream loadavgFile{"/proc/loadavg"}; 226 std::string line; 227 std::getline(loadavgFile, line); 228 229 size_t count = 3; 230 for (size_t i = 0; i < count; i++) 231 { 232 auto pos = line.find(" "); 233 if (pos == std::string::npos) 234 { 235 return {}; 236 } 237 238 if (i != count - 1) 239 { 240 loadavg.append(line.substr(0, pos + 1)); 241 } 242 else 243 { 244 loadavg.append(line.substr(0, pos)); 245 } 246 247 line = line.substr(pos + 1); 248 } 249 250 return loadavg; 251 } 252 253 /** 254 * @brief Returns the 'send event logs to host' setting. 255 * 256 * @return bool - If sending PELs to the host is enabled. 257 */ 258 virtual bool getHostPELEnablement() const 259 { 260 return _sendPELsToHost; 261 } 262 263 /** 264 * @brief Returns the BMC state 265 * 266 * @return std::string - The BMC state property value 267 */ 268 virtual std::string getBMCState() const 269 { 270 return _bmcState; 271 } 272 273 /** 274 * @brief Returns the Chassis state 275 * 276 * @return std::string - The chassis state property value 277 */ 278 virtual std::string getChassisState() const 279 { 280 return _chassisState; 281 } 282 283 /** 284 * @brief Returns the chassis requested power 285 * transition value. 286 * 287 * @return std::string - The chassis transition property 288 */ 289 virtual std::string getChassisTransition() const 290 { 291 return _chassisTransition; 292 } 293 294 /** 295 * @brief Returns the Host state 296 * 297 * @return std::string - The Host state property value 298 */ 299 virtual std::string getHostState() const 300 { 301 return _hostState; 302 } 303 304 /** 305 * @brief Returns the Boot state 306 * 307 * @return std::string - The Boot state property value 308 */ 309 virtual std::string getBootState() const 310 { 311 return _bootState; 312 } 313 314 /** 315 * @brief Returns the motherboard CCIN 316 * 317 * @return std::string The motherboard CCIN 318 */ 319 virtual std::string getMotherboardCCIN() const = 0; 320 321 /** 322 * @brief Returns the system IM 323 * 324 * @return std::string The system IM 325 */ 326 virtual std::vector<uint8_t> getSystemIMKeyword() const = 0; 327 328 /** 329 * @brief Get the fields from the inventory necessary for doing 330 * a callout on an inventory path. 331 * 332 * @param[in] inventoryPath - The item to get the data for 333 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword 334 * @param[out] ccin - Filled in with the VINI/CC keyword 335 * @param[out] serialNumber - Filled in with the VINI/SN keyword 336 */ 337 virtual void getHWCalloutFields( 338 const std::string& inventoryPath, std::string& fruPartNumber, 339 std::string& ccin, std::string& serialNumber) const = 0; 340 341 /** 342 * @brief Get the location code for an inventory item. 343 * 344 * @param[in] inventoryPath - The item to get the data for 345 * 346 * @return std::string - The location code 347 */ 348 virtual std::string 349 getLocationCode(const std::string& inventoryPath) const = 0; 350 351 /** 352 * @brief Get the list of system type names the system is called. 353 * 354 * @return std::vector<std::string> - The list of names 355 */ 356 virtual std::vector<std::string> getSystemNames() const = 0; 357 358 /** 359 * @brief Fills in the placeholder 'Ufcs' in the passed in location 360 * code with the machine feature code and serial number, which 361 * is needed to create a valid location code. 362 * 363 * @param[in] locationCode - Location code value starting with Ufcs-, and 364 * if that isn't present it will be added first. 365 * 366 * @param[in] node - The node number the location is on. 367 * 368 * @return std::string - The expanded location code 369 */ 370 virtual std::string expandLocationCode(const std::string& locationCode, 371 uint16_t node) const = 0; 372 373 /** 374 * @brief Returns the inventory paths for the FRU that the location 375 * code represents. 376 * 377 * @param[in] locationCode - If an expanded location code, then the 378 * full location code. 379 * If not expanded, a location code value 380 * starting with Ufcs-, and if that isn't 381 * present it will be added first. 382 * 383 * @param[in] node - The node number the location is on. Ignored if the 384 * expanded location code is passed in. 385 * 386 * @param[in] expanded - If the location code already has the relevent 387 * VPD fields embedded in it. 388 * 389 * @return std::vector<std::string> - The inventory D-Bus objects 390 */ 391 virtual std::vector<std::string> 392 getInventoryFromLocCode(const std::string& LocationCode, uint16_t node, 393 bool expanded) const = 0; 394 395 /** 396 * @brief Sets the Asserted property on the LED group passed in. 397 * 398 * @param[in] ledGroup - The LED group D-Bus path 399 * @param[in] value - The value to set it to 400 */ 401 virtual void assertLEDGroup(const std::string& ledGroup, 402 bool value) const = 0; 403 404 /** 405 * @brief Sets the Functional property on the OperationalStatus 406 * interface on a D-Bus object. 407 * 408 * @param[in] objectPath - The D-Bus object path 409 * @param[in] functional - The value 410 */ 411 virtual void setFunctional(const std::string& objectPath, 412 bool functional) const = 0; 413 414 /** 415 * @brief Sets the critical association on the D-Bus object. 416 * 417 * @param[in] objectPath - The D-Bus object path 418 */ 419 virtual void 420 setCriticalAssociation(const std::string& objectPath) const = 0; 421 422 /** 423 * @brief Returns the manufacturing QuiesceOnError property 424 * 425 * @return bool - Manufacturing QuiesceOnError property 426 */ 427 virtual bool getQuiesceOnError() const = 0; 428 429 /** 430 * @brief Split location code into base and connector segments 431 * 432 * A location code that ends in '-Tx', where 'x' is a number, 433 * represents a connector, such as a USB cable connector. 434 * 435 * This function splits the passed in location code into a 436 * base and connector segment. e.g.: 437 * P0-T1 -> ['P0', '-T1'] 438 * P0 -> ['P0', ''] 439 * 440 * @param[in] locationCode - location code to split 441 * @return pair<string, string> - The base and connector segments 442 */ 443 static std::pair<std::string, std::string> 444 extractConnectorFromLocCode(const std::string& locationCode); 445 446 /** 447 * @brief Returns the dump status 448 * 449 * @return bool dump status 450 */ 451 virtual std::vector<bool> 452 checkDumpStatus(const std::vector<std::string>& type) const = 0; 453 454 /** 455 * @brief Create guard record 456 * 457 * @param[in] binPath: phal devtree binary path used as key 458 * @param[in] type: Guard type 459 * @param[in] logPath: error log entry object path 460 */ 461 virtual void createGuardRecord(const std::vector<uint8_t>& binPath, 462 const std::string& type, 463 const std::string& logPath) const = 0; 464 465 /** 466 * @brief Create Progress SRC property on the boot progress 467 * interface on a D-Bus object. 468 * 469 * @param[in] priSRC - Primary SRC value (e.g. BD8D1001) 470 * @param[in] srcStruct - Full SRC base structure 471 */ 472 virtual void 473 createProgressSRC(const uint64_t& priSRC, 474 const std::vector<uint8_t>& srcStruct) const = 0; 475 476 /** 477 * @brief Get the list of unresolved OpenBMC event log ids that have an 478 * associated hardware isolation entry. 479 * 480 * @return std::vector<uint32_t> - The list of log ids 481 */ 482 virtual std::vector<uint32_t> getLogIDWithHwIsolation() const = 0; 483 484 /** 485 * @brief Returns the latest raw progress SRC from the State.Boot.Raw 486 * D-Bus interface. 487 * 488 * @return std::vector<uint8_t> - The progress SRC bytes 489 */ 490 virtual std::vector<uint8_t> getRawProgressSRC() const = 0; 491 492 /** 493 * @brief Returns the FRUs DI property value hosted on the VINI iterface for 494 * the given location code. 495 * 496 * @param[in] locationCode - The location code of the FRU 497 * 498 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or 499 * std::nullopt 500 */ 501 virtual std::optional<std::vector<uint8_t>> 502 getDIProperty(const std::string& locationCode) const = 0; 503 504 /** 505 * @brief Wrpper API to call pHAL API 'getFRUType()' and check whether the 506 * given location code is DIMM or not 507 * 508 * @param[in] locCode - The location code of the FRU 509 * 510 * @return - true, if the given location code is DIMM 511 * - false, if the given location code is not DIMM or if it fails to 512 * determine the FRU type. 513 */ 514 bool isDIMM(const std::string& locCode); 515 516 /** 517 * @brief Check whether the given location code present in the cache 518 * memory 519 * 520 * @param[in] locCode - The location code of the FRU 521 * 522 * @return true, if the given location code present in cache and is a DIMM 523 * false, if the given location code present in cache, but a non 524 * DIMM FRU 525 * std::nullopt, if the given location code is not present in the 526 * cache. 527 */ 528 std::optional<bool> isDIMMLocCode(const std::string& locCode) const; 529 530 /** 531 * @brief add the given location code to the cache memory 532 * 533 * @param[in] locCode - The location code of the FRU 534 * @param[in] isFRUDIMM - true indicates the FRU is a DIMM 535 * false indicates the FRU is a non DIMM 536 * 537 */ 538 void addDIMMLocCode(const std::string& locCode, bool isFRUDIMM); 539 540 /** 541 * @brief Finds all D-Bus Associated paths that contain any of the 542 * interfaces passed in, by using GetAssociatedSubTreePaths. 543 * 544 * @param[in] associatedPath - The D-Bus object path 545 * @param[in] subtree - The subtree path for which the result should be 546 * fetched 547 * @param[in] depth - The maximum subtree depth for which results should be 548 * fetched 549 * @param[in] interfaces - The desired interfaces 550 * 551 * @return The D-Bus paths. 552 */ 553 virtual DBusPathList getAssociatedPaths( 554 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth, 555 const DBusInterfaceList& interfaces) const = 0; 556 557 protected: 558 /** 559 * @brief Sets the host on/off state and runs any 560 * callback functions (if there was a change). 561 */ 562 void setHostUp(bool hostUp) 563 { 564 if (_hostUp != hostUp) 565 { 566 _hostUp = hostUp; 567 568 for (auto& [name, func] : _hostChangeCallbacks) 569 { 570 try 571 { 572 func(_hostUp); 573 } 574 catch (const std::exception& e) 575 { 576 lg2::error( 577 "A host state change callback threw an exception"); 578 } 579 } 580 } 581 } 582 583 /** 584 * @brief Runs the callback functions registered when 585 * FRUs become present. 586 */ 587 void setFruPresent(const std::string& locationCode) 588 { 589 for (const auto& [_, func] : _fruPresentCallbacks) 590 { 591 try 592 { 593 func(locationCode); 594 } 595 catch (const std::exception& e) 596 { 597 lg2::error("A FRU present callback threw an exception"); 598 } 599 } 600 } 601 602 /** 603 * @brief The hardware management console status. Always kept 604 * up to date. 605 */ 606 bool _hmcManaged = false; 607 608 /** 609 * @brief The host up status. Always kept up to date. 610 */ 611 bool _hostUp = false; 612 613 /** 614 * @brief The map of host state change subscriber 615 * names to callback functions. 616 */ 617 std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks; 618 619 /** 620 * @brief The map of FRU present subscriber 621 * names to callback functions. 622 */ 623 std::map<std::string, FRUPresentFunc> _fruPresentCallbacks; 624 625 /** 626 * @brief The BMC firmware version string 627 */ 628 std::string _bmcFWVersion; 629 630 /** 631 * @brief The server firmware version string 632 */ 633 std::string _serverFWVersion; 634 635 /** 636 * @brief The BMC firmware version ID string 637 */ 638 std::string _bmcFWVersionID; 639 640 /** 641 * @brief If sending PELs is enabled. 642 * 643 * This is usually set to false in manufacturing test. 644 */ 645 bool _sendPELsToHost = true; 646 647 /** 648 * @brief The BMC state property 649 */ 650 std::string _bmcState; 651 652 /** 653 * @brief The Chassis current power state property 654 */ 655 std::string _chassisState; 656 657 /** 658 * @brief The Chassis requested power transition property 659 */ 660 std::string _chassisTransition; 661 662 /** 663 * @brief The host state property 664 */ 665 std::string _hostState; 666 667 /** 668 * @brief The boot state property 669 */ 670 std::string _bootState; 671 672 /** 673 * @brief A cache storage for location code and its FRU Type 674 * - The key 'std::string' represents the locationCode of the FRU 675 * - The bool value - true indicates the FRU is a DIMM 676 * false indicates the FRU is a non DIMM. 677 */ 678 std::unordered_map<std::string, bool> _locationCache; 679 }; 680 681 /** 682 * @class DataInterface 683 * 684 * Concrete implementation of DataInterfaceBase. 685 */ 686 class DataInterface : public DataInterfaceBase 687 { 688 public: 689 DataInterface() = delete; 690 ~DataInterface() = default; 691 DataInterface(const DataInterface&) = default; 692 DataInterface& operator=(const DataInterface&) = default; 693 DataInterface(DataInterface&&) = default; 694 DataInterface& operator=(DataInterface&&) = default; 695 696 /** 697 * @brief Constructor 698 * 699 * @param[in] bus - The sdbusplus bus object 700 */ 701 explicit DataInterface(sdbusplus::bus_t& bus); 702 703 /** 704 * @brief Finds the D-Bus service name that hosts the 705 * passed in path and interface. 706 * 707 * @param[in] objectPath - The D-Bus object path 708 * @param[in] interface - The D-Bus interface 709 */ 710 DBusService getService(const std::string& objectPath, 711 const std::string& interface) const; 712 713 /** 714 * @brief Wrapper for the 'GetAll' properties method call 715 * 716 * @param[in] service - The D-Bus service to call it on 717 * @param[in] objectPath - The D-Bus object path 718 * @param[in] interface - The interface to get the props on 719 * 720 * @return DBusPropertyMap - The property results 721 */ 722 DBusPropertyMap getAllProperties(const std::string& service, 723 const std::string& objectPath, 724 const std::string& interface) const; 725 /** 726 * @brief Wrapper for the 'Get' properties method call 727 * 728 * @param[in] service - The D-Bus service to call it on 729 * @param[in] objectPath - The D-Bus object path 730 * @param[in] interface - The interface to get the property on 731 * @param[in] property - The property name 732 * @param[out] value - Filled in with the property value. 733 */ 734 void getProperty(const std::string& service, const std::string& objectPath, 735 const std::string& interface, const std::string& property, 736 DBusValue& value) const; 737 /** 738 * @brief Returns the machine Type/Model 739 * 740 * @return string - The machine Type/Model string 741 */ 742 std::string getMachineTypeModel() const override; 743 744 /** 745 * @brief Returns the machine serial number 746 * 747 * @return string - The machine serial number 748 */ 749 std::string getMachineSerialNumber() const override; 750 751 /** 752 * @brief Returns the motherboard CCIN 753 * 754 * @return std::string The motherboard CCIN 755 */ 756 std::string getMotherboardCCIN() const override; 757 758 /** 759 * @brief Returns the system IM 760 * 761 * @return std::vector The system IM keyword in 4 byte vector 762 */ 763 std::vector<uint8_t> getSystemIMKeyword() const override; 764 765 /** 766 * @brief Get the fields from the inventory necessary for doing 767 * a callout on an inventory path. 768 * 769 * @param[in] inventoryPath - The item to get the data for 770 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword 771 * @param[out] ccin - Filled in with the VINI/CC keyword 772 * @param[out] serialNumber - Filled in with the VINI/SN keyword 773 */ 774 void getHWCalloutFields(const std::string& inventoryPath, 775 std::string& fruPartNumber, std::string& ccin, 776 std::string& serialNumber) const override; 777 778 /** 779 * @brief Get the location code for an inventory item. 780 * 781 * Throws an exception if the inventory item doesn't have the 782 * location code interface. 783 * 784 * @param[in] inventoryPath - The item to get the data for 785 * 786 * @return std::string - The location code 787 */ 788 std::string 789 getLocationCode(const std::string& inventoryPath) const override; 790 791 /** 792 * @brief Get the list of system type names the system is called. 793 * 794 * @return std::vector<std::string> - The list of names 795 */ 796 std::vector<std::string> getSystemNames() const override; 797 798 /** 799 * @brief Fills in the placeholder 'Ufcs' in the passed in location 800 * code with the machine feature code and serial number, which 801 * is needed to create a valid location code. 802 * 803 * @param[in] locationCode - Location code value starting with Ufcs-, and 804 * if that isn't present it will be added first. 805 * 806 * @param[in] node - The node number the location is one. 807 * 808 * @return std::string - The expanded location code 809 */ 810 std::string expandLocationCode(const std::string& locationCode, 811 uint16_t node) const override; 812 813 /** 814 * @brief Returns the inventory paths for the FRU that the location 815 * code represents. 816 * 817 * @param[in] locationCode - If an expanded location code, then the 818 * full location code. 819 * If not expanded, a location code value 820 * starting with Ufcs-, and if that isn't 821 * present it will be added first. 822 * 823 * @param[in] node - The node number the location is on. Ignored if the 824 * expanded location code is passed in. 825 * 826 * @param[in] expanded - If the location code already has the relevent 827 * VPD fields embedded in it. 828 * 829 * @return std::vector<std::string> - The inventory D-Bus objects 830 */ 831 std::vector<std::string> 832 getInventoryFromLocCode(const std::string& locationCode, uint16_t node, 833 bool expanded) const override; 834 835 /** 836 * @brief Sets the Asserted property on the LED group passed in. 837 * 838 * @param[in] ledGroup - The LED group D-Bus path 839 * @param[in] value - The value to set it to 840 */ 841 void assertLEDGroup(const std::string& ledGroup, bool value) const override; 842 843 /** 844 * @brief Sets the Functional property on the OperationalStatus 845 * interface on a D-Bus object. 846 * 847 * @param[in] objectPath - The D-Bus object path 848 * @param[in] functional - The value 849 */ 850 void setFunctional(const std::string& objectPath, 851 bool functional) const override; 852 853 /** 854 * @brief Sets the critical association on the D-Bus object. 855 * 856 * @param[in] objectPath - The D-Bus object path 857 */ 858 void setCriticalAssociation(const std::string& objectPath) const override; 859 860 /** 861 * @brief Returns the manufacturing QuiesceOnError property 862 * 863 * @return bool - Manufacturing QuiesceOnError property 864 */ 865 bool getQuiesceOnError() const override; 866 867 /** 868 * @brief Returns the dump status 869 * 870 * @param[in] type - The dump type to check for 871 * 872 * @return bool dump status 873 */ 874 std::vector<bool> 875 checkDumpStatus(const std::vector<std::string>& type) const override; 876 877 /** 878 * @brief Create guard record 879 * 880 * @param[in] binPath: phal devtree binary path used as key 881 * @param[in] type: Guard type 882 * @param[in] logPath: error log entry object path 883 */ 884 void createGuardRecord(const std::vector<uint8_t>& binPath, 885 const std::string& type, 886 const std::string& logPath) const override; 887 888 /** 889 * @brief Create Progress SRC property on the boot progress 890 * interface on a D-Bus object. 891 * 892 * @param[in] priSRC - Primary SRC value 893 * @param[in] srcStruct - Full SRC base structure 894 */ 895 void 896 createProgressSRC(const uint64_t& priSRC, 897 const std::vector<uint8_t>& srcStruct) const override; 898 899 /** 900 * @brief Get the list of unresolved OpenBMC event log ids that have an 901 * associated hardware isolation entry. 902 * 903 * @return std::vector<uint32_t> - The list of log ids 904 */ 905 std::vector<uint32_t> getLogIDWithHwIsolation() const override; 906 907 /** 908 * @brief Returns the latest raw progress SRC from the State.Boot.Raw 909 * D-Bus interface. 910 * 911 * @return std::vector<uint8_t>: The progress SRC bytes 912 */ 913 std::vector<uint8_t> getRawProgressSRC() const override; 914 915 /** 916 * @brief Returns the FRUs DI property value hosted on the VINI iterface for 917 * the given location code. 918 * 919 * @param[in] locationCode - The location code of the FRU 920 * 921 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or 922 * std::nullopt 923 */ 924 std::optional<std::vector<uint8_t>> 925 getDIProperty(const std::string& locationCode) const override; 926 927 /** 928 * @brief Finds all D-Bus Associated paths that contain any of the 929 * interfaces passed in, by using GetAssociatedSubTreePaths. 930 * 931 * @param[in] associatedPath - The D-Bus object path 932 * @param[in] subtree - The subtree path for which the result should be 933 * fetched 934 * @param[in] depth - The maximum subtree depth for which results should be 935 * fetched 936 * @param[in] interfaces - The desired interfaces 937 * 938 * @return The D-Bus paths. 939 */ 940 DBusPathList getAssociatedPaths( 941 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth, 942 const DBusInterfaceList& interfaces) const override; 943 944 private: 945 /** 946 * @brief Reads the BMC firmware version string and puts it into 947 * _bmcFWVersion. 948 */ 949 void readBMCFWVersion(); 950 951 /** 952 * @brief Reads the server firmware version string and puts it into 953 * _serverFWVersion. 954 */ 955 void readServerFWVersion(); 956 957 /** 958 * @brief Reads the BMC firmware version ID and puts it into 959 * _bmcFWVersionID. 960 */ 961 void readBMCFWVersionID(); 962 963 /** 964 * @brief Finds all D-Bus paths that contain any of the interfaces 965 * passed in, by using GetSubTreePaths. 966 * 967 * @param[in] interfaces - The desired interfaces 968 * 969 * @return The D-Bus paths. 970 */ 971 DBusPathList getPaths(const DBusInterfaceList& interfaces) const; 972 973 /** 974 * @brief The interfacesAdded callback used on the inventory to 975 * find the D-Bus object that has the motherboard interface. 976 * When the motherboard is found, it then adds a PropertyWatcher 977 * for the motherboard CCIN. 978 */ 979 void motherboardIfaceAdded(sdbusplus::message_t& msg); 980 981 /** 982 * @brief Start watching for the hotpluggable FRUs to become 983 * present. 984 */ 985 void startFruPlugWatch(); 986 987 /** 988 * @brief Create a D-Bus match object for the Present property 989 * to change on the path passed in. 990 * @param[in] path - The path to watch. 991 */ 992 void addHotplugWatch(const std::string& path); 993 994 /** 995 * @brief Callback when an inventory interface was added. 996 * 997 * Only does something if it's one of the hotpluggable FRUs, 998 * in which case it will treat it as a hotplug if the 999 * Present property is true. 1000 * 1001 * @param[in] msg - The InterfacesAdded signal contents. 1002 */ 1003 void inventoryIfaceAdded(sdbusplus::message_t& msg); 1004 1005 /** 1006 * @brief Callback when the Present property changes. 1007 * 1008 * If present, will run the registered callbacks. 1009 * 1010 * @param[in] msg - The PropertiesChanged signal contents. 1011 */ 1012 void presenceChanged(sdbusplus::message_t& msg); 1013 1014 /** 1015 * @brief If the Present property is in the properties map 1016 * passed in and it is true, notify the subscribers. 1017 * 1018 * @param[in] path - The object path of the inventory item. 1019 * @param[in] properties - The properties map 1020 */ 1021 void notifyPresenceSubsribers(const std::string& path, 1022 const DBusPropertyMap& properties); 1023 1024 /** 1025 * @brief Adds the Ufcs- prefix to the location code passed in 1026 * if necessary. 1027 * 1028 * Needed because the location codes that come back from the 1029 * message registry and device callout JSON don't have it. 1030 * 1031 * @param[in] - The location code without a prefix, like P1-C1 1032 * 1033 * @return std::string - The location code with the prefix 1034 */ 1035 static std::string addLocationCodePrefix(const std::string& locationCode); 1036 1037 /** 1038 * @brief A helper API to check whether the PHAL device tree is exists, 1039 * ensuring the PHAL init API can be invoked. 1040 * 1041 * @return true if the PHAL device tree is exists, otherwise false 1042 */ 1043 bool isPHALDevTreeExist() const; 1044 1045 #ifdef PEL_ENABLE_PHAL 1046 /** 1047 * @brief A helper API to init PHAL libraries 1048 * 1049 * @return None 1050 */ 1051 void initPHAL(); 1052 #endif // PEL_ENABLE_PHAL 1053 1054 /** 1055 * @brief A helper API to subscribe to systemd signals 1056 * 1057 * @return None 1058 */ 1059 void subscribeToSystemdSignals(); 1060 1061 /** 1062 * @brief A helper API to unsubscribe to systemd signals 1063 * 1064 * @return None 1065 */ 1066 void unsubscribeFromSystemdSignals(); 1067 1068 /** 1069 * @brief The D-Bus property or interface watchers that have callbacks 1070 * registered that will set members in this class when 1071 * they change. 1072 */ 1073 std::vector<std::unique_ptr<DBusWatcher>> _properties; 1074 1075 std::unique_ptr<sdbusplus::bus::match_t> _invIaMatch; 1076 1077 /** 1078 * @brief The matches for watching for hotplugs. 1079 * 1080 * A map so we can check that we never get duplicates. 1081 */ 1082 std::map<std::string, std::unique_ptr<sdbusplus::bus::match_t>> 1083 _invPresentMatches; 1084 1085 /** 1086 * @brief The sdbusplus bus object for making D-Bus calls. 1087 */ 1088 sdbusplus::bus_t& _bus; 1089 1090 /** 1091 * @brief Watcher to check "openpower-update-bios-attr-table" service 1092 * is "done" to init PHAL libraires 1093 */ 1094 std::unique_ptr<sdbusplus::bus::match_t> _systemdMatch; 1095 1096 /** 1097 * @brief A slot object for async dbus call 1098 */ 1099 sdbusplus::slot_t _systemdSlot; 1100 }; 1101 1102 } // namespace pels 1103 } // namespace openpower 1104