Jonathan Doman | de7a6dd | 2023-05-03 10:54:08 -0700 | [diff] [blame] | 1 | #include "ipmisnoop.hpp" |
| 2 | |
| 3 | std::vector<std::unique_ptr<IpmiPostReporter>> reporters; |
| 4 | bool sevenSegmentLedEnabled = true; |
| 5 | std::vector<gpiod::line> led_lines; |
| 6 | |
| 7 | uint32_t getSelectorPosition(sdbusplus::bus_t& bus) |
| 8 | { |
| 9 | const std::string propertyName = "Position"; |
| 10 | |
| 11 | auto method = bus.new_method_call(selectorService.c_str(), |
| 12 | selectorObject.c_str(), |
| 13 | "org.freedesktop.DBus.Properties", "Get"); |
| 14 | method.append(selectorIface.c_str(), propertyName); |
| 15 | |
| 16 | try |
| 17 | { |
| 18 | std::variant<uint32_t> value{}; |
| 19 | auto reply = bus.call(method); |
| 20 | reply.read(value); |
| 21 | return std::get<uint32_t>(value); |
| 22 | } |
| 23 | catch (const sdbusplus::exception_t& ex) |
| 24 | { |
| 25 | std::cerr << "GetProperty call failed. " << ex.what() << std::endl; |
| 26 | return 0; |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | // Configure the seven segment display connected GPIOs direction |
| 31 | static int configGPIODirOutput() |
| 32 | { |
| 33 | std::string gpioStr; |
| 34 | // Need to define gpio names LED_POST_CODE_0 to 8 in dts file |
| 35 | std::string gpioName = "LED_POST_CODE_"; |
| 36 | const int value = 0; |
| 37 | |
| 38 | for (int iteration = 0; iteration < 8; iteration++) |
| 39 | { |
| 40 | gpioStr = gpioName + std::to_string(iteration); |
| 41 | gpiod::line gpioLine = gpiod::find_line(gpioStr); |
| 42 | |
| 43 | if (!gpioLine) |
| 44 | { |
| 45 | std::string errMsg = "Failed to find the " + gpioStr + " line"; |
| 46 | std::cerr << errMsg.c_str() << std::endl; |
| 47 | |
| 48 | /* sevenSegmentLedEnabled flag is unset when GPIO pins are not there |
| 49 | * 7 seg display for fewer platforms. |
| 50 | */ |
| 51 | sevenSegmentLedEnabled = false; |
| 52 | return -1; |
| 53 | } |
| 54 | |
| 55 | led_lines.push_back(gpioLine); |
| 56 | // Request GPIO output to specified value |
| 57 | try |
| 58 | { |
| 59 | gpioLine.request({__FUNCTION__, |
| 60 | gpiod::line_request::DIRECTION_OUTPUT, |
| 61 | gpiod::line_request::FLAG_ACTIVE_LOW}, |
| 62 | value); |
| 63 | } |
| 64 | catch (std::exception&) |
| 65 | { |
| 66 | std::string errMsg = "Failed to request " + gpioStr + " output"; |
| 67 | std::cerr << errMsg.c_str() << std::endl; |
| 68 | return -1; |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | return 0; |
| 73 | } |
| 74 | |
| 75 | // Display the received postcode into seven segment display |
| 76 | int IpmiPostReporter::postCodeDisplay(uint8_t status) |
| 77 | { |
| 78 | for (int iteration = 0; iteration < 8; iteration++) |
| 79 | { |
| 80 | // split byte to write into GPIOs |
| 81 | int value = !((status >> iteration) & 0x01); |
| 82 | |
| 83 | led_lines[iteration].set_value(value); |
| 84 | } |
| 85 | return 0; |
| 86 | } |
| 87 | |
| 88 | void IpmiPostReporter::getSelectorPositionSignal(sdbusplus::bus_t& bus) |
| 89 | { |
| 90 | constexpr uint8_t minPositionVal = 0; |
| 91 | constexpr uint8_t maxPositionVal = 5; |
| 92 | |
| 93 | size_t posVal = 0; |
| 94 | |
| 95 | static auto matchSignal = std::make_unique<sdbusplus::bus::match_t>( |
| 96 | bus, |
| 97 | sdbusplus::bus::match::rules::propertiesChanged(selectorObject, |
| 98 | selectorIface), |
| 99 | [&](sdbusplus::message_t& msg) { |
| 100 | std::string objectName; |
| 101 | std::map<std::string, Selector::PropertiesVariant> msgData; |
| 102 | msg.read(objectName, msgData); |
| 103 | |
| 104 | auto valPropMap = msgData.find("Position"); |
| 105 | { |
| 106 | if (valPropMap == msgData.end()) |
| 107 | { |
| 108 | std::cerr << "Position property not found " << std::endl; |
| 109 | return; |
| 110 | } |
| 111 | |
| 112 | posVal = std::get<size_t>(valPropMap->second); |
| 113 | |
| 114 | if (posVal > minPositionVal && posVal < maxPositionVal) |
| 115 | { |
| 116 | std::tuple<uint64_t, secondary_post_code_t> postcodes = |
| 117 | reporters[posVal - 1]->value(); |
| 118 | uint64_t postcode = std::get<uint64_t>(postcodes); |
| 119 | |
| 120 | // write postcode into seven segment display |
| 121 | if (postCodeDisplay(postcode) < 0) |
| 122 | { |
| 123 | fprintf(stderr, "Error in display the postcode\n"); |
| 124 | } |
| 125 | } |
| 126 | } |
Patrick Williams | bebbda9 | 2023-10-20 11:19:03 -0500 | [diff] [blame] | 127 | }); |
Jonathan Doman | de7a6dd | 2023-05-03 10:54:08 -0700 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | // handle muti-host D-bus |
| 131 | int postCodeIpmiHandler(const std::string& snoopObject, |
| 132 | const std::string& snoopDbus, sdbusplus::bus_t& bus, |
| 133 | std::span<std::string> host) |
| 134 | { |
| 135 | int ret = 0; |
| 136 | |
| 137 | try |
| 138 | { |
| 139 | for (size_t iteration = 0; iteration < host.size(); iteration++) |
| 140 | { |
| 141 | std::string objPathInst = snoopObject + host[iteration]; |
| 142 | |
| 143 | sdbusplus::server::manager_t m{bus, objPathInst.c_str()}; |
| 144 | |
| 145 | /* Create a monitor object and let it do all the rest */ |
| 146 | reporters.emplace_back( |
| 147 | std::make_unique<IpmiPostReporter>(bus, objPathInst.c_str())); |
| 148 | |
| 149 | reporters[iteration]->emit_object_added(); |
| 150 | } |
| 151 | |
| 152 | bus.request_name(snoopDbus.c_str()); |
| 153 | |
| 154 | /* sevenSegmentLedEnabled flag is unset when GPIO pins are not there 7 |
| 155 | seg display for fewer platforms. So, the code for postcode dispay and |
| 156 | Get Selector position can be skipped in those platforms. |
| 157 | */ |
| 158 | if (sevenSegmentLedEnabled) |
| 159 | { |
| 160 | reporters[0]->getSelectorPositionSignal(bus); |
| 161 | } |
| 162 | else |
| 163 | { |
| 164 | reporters.clear(); |
| 165 | } |
| 166 | } |
| 167 | catch (const std::exception& e) |
| 168 | { |
| 169 | fprintf(stderr, "%s\n", e.what()); |
| 170 | } |
| 171 | |
| 172 | // Configure seven segment dsiplay connected to GPIOs as output |
| 173 | ret = configGPIODirOutput(); |
| 174 | if (ret < 0) |
| 175 | { |
| 176 | fprintf(stderr, "Failed find the gpio line. Cannot display postcodes " |
| 177 | "in seven segment display..\n"); |
| 178 | } |
| 179 | |
| 180 | while (true) |
| 181 | { |
| 182 | bus.process_discard(); |
| 183 | bus.wait(); |
| 184 | } |
| 185 | exit(EXIT_SUCCESS); |
| 186 | } |