1 #pragma once 2 3 #include "lpcsnoop/snoop.hpp" 4 5 #include <boost/asio.hpp> 6 #include <gpiod.hpp> 7 #include <sdbusplus/asio/connection.hpp> 8 #include <sdbusplus/asio/object_server.hpp> 9 #include <sdbusplus/asio/property.hpp> 10 #include <sdbusplus/bus.hpp> 11 #include <sdbusplus/server.hpp> 12 #include <xyz/openbmc_project/Chassis/Buttons/HostSelector/server.hpp> 13 #include <xyz/openbmc_project/State/Boot/Raw/server.hpp> 14 15 #include <filesystem> 16 #include <iostream> 17 #include <span> 18 19 const std::string ipmiSnoopObject = "/xyz/openbmc_project/state/boot/raw"; 20 21 const int hostParseIdx = 3; 22 const int maxPostcode = 255; 23 const int maxPosition = 4; 24 25 extern bool sevenSegmentLedEnabled; 26 27 extern std::vector<gpiod::line> led_lines; 28 29 using Selector = 30 sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::HostSelector; 31 32 const std::string selectorService = "xyz.openbmc_project.Chassis.Buttons"; 33 const std::string selectorObject = 34 "/xyz/openbmc_project/Chassis/Buttons/HostSelector"; 35 const std::string selectorIface = 36 "xyz.openbmc_project.Chassis.Buttons.HostSelector"; 37 38 const std::string rawObject = "/xyz/openbmc_project/state/boot"; 39 const std::string rawIface = "xyz.openbmc_project.State.Boot.Raw"; 40 const std::string rawService = "xyz.openbmc_project.State.Boot.Raw"; 41 42 int postCodeIpmiHandler(const std::string& snoopObject, 43 const std::string& snoopDbus, sdbusplus::bus_t& bus, 44 std::span<std::string> host); 45 46 uint32_t getSelectorPosition(sdbusplus::bus_t& bus); 47 48 struct IpmiPostReporter : PostObject 49 { 50 IpmiPostReporter(sdbusplus::bus_t& bus, const char* objPath) : 51 PostObject(bus, objPath), bus(bus), 52 propertiesChangedSignalRaw( 53 bus, 54 sdbusplus::bus::match::rules::propertiesChanged(objPath, rawIface), 55 56 [this, &bus](sdbusplus::message_t& msg) { 57 using primarycode_t = uint64_t; 58 using secondarycode_t = std::vector<uint8_t>; 59 using postcode_t = std::tuple<primarycode_t, secondarycode_t>; 60 61 /* sevenSegmentLedEnabled flag is set when GPIO pins are not 62 there 7 seg display for fewer platforms. So, the code for 63 postcode dispay and Get Selector position can be skipped in 64 those platforms. 65 */ 66 if (!sevenSegmentLedEnabled) 67 { 68 return; 69 } 70 71 std::string objectName; 72 std::string InterfaceName; 73 std::map<std::string, std::variant<postcode_t>> msgData; 74 msg.read(InterfaceName, msgData); 75 76 std::filesystem::path name(msg.get_path()); 77 objectName = name.filename(); 78 79 std::string hostNumStr = objectName.substr(hostParseIdx); 80 size_t hostNum = std::stoi(hostNumStr); 81 82 size_t position = getSelectorPosition(bus); 83 84 if (position > maxPosition) 85 { 86 std::cerr << "Invalid position. Position should be 1 to 4 " 87 "for all hosts " 88 << std::endl; 89 } 90 91 // Check if it was the Value property that changed. 92 auto valPropMap = msgData.find("Value"); 93 if (valPropMap == msgData.end()) 94 { 95 std::cerr << "Value property is not found " << std::endl; 96 return; 97 } 98 uint64_t postcode = 99 std::get<0>(std::get<postcode_t>(valPropMap->second)); 100 101 if (postcode <= maxPostcode) 102 { 103 if (position == hostNum) 104 { 105 uint8_t postcode_8bit = 106 static_cast<uint8_t>(postcode & 0x0000FF); 107 108 // write postcode into seven segment display 109 if (postCodeDisplay(postcode_8bit) < 0) 110 { 111 fprintf(stderr, "Error in display the postcode\n"); 112 } 113 } 114 else 115 { 116 fprintf(stderr, "Host Selector Position and host " 117 "number is not matched..\n"); 118 } 119 } 120 else 121 { 122 fprintf(stderr, "invalid postcode value \n"); 123 } 124 }) 125 {} 126 127 sdbusplus::bus_t& bus; 128 sdbusplus::bus::match_t propertiesChangedSignalRaw; 129 int postCodeDisplay(uint8_t); 130 void getSelectorPositionSignal(sdbusplus::bus_t& bus); 131 }; 132