| #pragma once |
| |
| #include "lpcsnoop/snoop.hpp" |
| |
| #include <boost/asio.hpp> |
| #include <gpiod.hpp> |
| #include <sdbusplus/asio/connection.hpp> |
| #include <sdbusplus/asio/object_server.hpp> |
| #include <sdbusplus/asio/property.hpp> |
| #include <sdbusplus/bus.hpp> |
| #include <sdbusplus/server.hpp> |
| #include <xyz/openbmc_project/Chassis/Buttons/HostSelector/server.hpp> |
| #include <xyz/openbmc_project/State/Boot/Raw/server.hpp> |
| |
| #include <filesystem> |
| #include <iostream> |
| #include <span> |
| |
| const std::string ipmiSnoopObject = "/xyz/openbmc_project/state/boot/raw"; |
| |
| const int hostParseIdx = 3; |
| const int maxPosition = 4; |
| |
| extern bool sevenSegmentLedEnabled; |
| |
| extern std::vector<gpiod::line> led_lines; |
| |
| using Selector = |
| sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::HostSelector; |
| |
| const std::string selectorService = "xyz.openbmc_project.Chassis.Buttons"; |
| const std::string selectorObject = |
| "/xyz/openbmc_project/Chassis/Buttons/HostSelector"; |
| const std::string selectorIface = |
| "xyz.openbmc_project.Chassis.Buttons.HostSelector"; |
| |
| const std::string rawObject = "/xyz/openbmc_project/state/boot"; |
| const std::string rawIface = "xyz.openbmc_project.State.Boot.Raw"; |
| const std::string rawService = "xyz.openbmc_project.State.Boot.Raw"; |
| |
| int postCodeIpmiHandler(const std::string& snoopObject, |
| const std::string& snoopDbus, sdbusplus::bus_t& bus, |
| std::span<std::string> host); |
| |
| uint32_t getSelectorPosition(sdbusplus::bus_t& bus); |
| |
| struct IpmiPostReporter : PostObject |
| { |
| IpmiPostReporter(sdbusplus::bus_t& bus, const char* objPath) : |
| PostObject(bus, objPath), bus(bus), |
| propertiesChangedSignalRaw( |
| bus, |
| sdbusplus::bus::match::rules::propertiesChanged(objPath, rawIface), |
| |
| [this, &bus](sdbusplus::message_t& msg) { |
| using primarycode_t = std::vector<uint8_t>; |
| using secondarycode_t = std::vector<uint8_t>; |
| using postcode_t = std::tuple<primarycode_t, secondarycode_t>; |
| |
| /* sevenSegmentLedEnabled flag is set when GPIO pins are not |
| there 7 seg display for fewer platforms. So, the code for |
| postcode display and Get Selector position can be skipped in |
| those platforms. |
| */ |
| if (!sevenSegmentLedEnabled) |
| { |
| return; |
| } |
| |
| std::string objectName; |
| std::string InterfaceName; |
| std::map<std::string, std::variant<postcode_t>> msgData; |
| msg.read(InterfaceName, msgData); |
| |
| std::filesystem::path name(msg.get_path()); |
| objectName = name.filename(); |
| |
| std::string hostNumStr = objectName.substr(hostParseIdx); |
| size_t hostNum = std::stoi(hostNumStr); |
| |
| size_t position = getSelectorPosition(bus); |
| |
| if (position > maxPosition) |
| { |
| std::cerr << "Invalid position. Position should be 1 to 4 " |
| "for all hosts " |
| << std::endl; |
| } |
| |
| // Check if it was the Value property that changed. |
| auto valPropMap = msgData.find("Value"); |
| if (valPropMap == msgData.end()) |
| { |
| std::cerr << "Value property is not found " << std::endl; |
| return; |
| } |
| auto postcode = |
| std::get<0>(std::get<postcode_t>(valPropMap->second)); |
| |
| if (postcode.size() == 1) |
| { |
| if (position == hostNum) |
| { |
| // write postcode into seven segment display |
| if (postCodeDisplay(postcode[0]) < 0) |
| { |
| fprintf(stderr, "Error in display the postcode\n"); |
| } |
| } |
| else |
| { |
| fprintf(stderr, "Host Selector Position and host " |
| "number is not matched..\n"); |
| } |
| } |
| else |
| { |
| fprintf(stderr, "invalid postcode value \n"); |
| } |
| }) |
| {} |
| |
| sdbusplus::bus_t& bus; |
| sdbusplus::bus::match_t propertiesChangedSignalRaw; |
| int postCodeDisplay(uint8_t); |
| void getSelectorPositionSignal(sdbusplus::bus_t& bus); |
| }; |