1 
2 #pragma once
3 #include "button_factory.hpp"
4 #include "button_interface.hpp"
5 #include "common.hpp"
6 #include "config.hpp"
7 #include "gpio.hpp"
8 #include "xyz/openbmc_project/Chassis/Buttons/HostSelector/server.hpp"
9 #include "xyz/openbmc_project/Chassis/Common/error.hpp"
10 #include "xyz/openbmc_project/Inventory/Item/server.hpp"
11 
12 #include <unistd.h>
13 
14 #include <phosphor-logging/elog-errors.hpp>
15 #include <sdbusplus/bus.hpp>
16 #include <sdbusplus/bus/match.hpp>
17 static constexpr std::string_view DEBUG_CARD_PRESENT_GPIO =
18     "debug_card_present";
19 static constexpr std::string_view SERIAL_CONSOLE_SWITCH = "SERIAL_UART_MUX";
20 
21 class SerialUartMux final : public ButtonIface
22 {
23   public:
SerialUartMux(sdbusplus::bus_t & bus,const char * path,EventPtr & event,ButtonConfig & buttonCfg)24     SerialUartMux(sdbusplus::bus_t& bus, [[maybe_unused]] const char* path,
25                   EventPtr& event, ButtonConfig& buttonCfg) :
26         ButtonIface(bus, event, buttonCfg)
27     {
28         init();
29 
30         // read the platform specific config of host number to uart mux map
31         std::unordered_map<std::string, size_t> uartMuxMapJson =
32             buttonCfg.extraJsonInfo.at("serial_uart_mux_map")
33                 .get<decltype(uartMuxMapJson)>();
34         for (auto& [key, value] : uartMuxMapJson)
35         {
36             auto index = std::stoi(key);
37             serialUartMuxMap[index] = value;
38         }
39         if (buttonCfg.gpios.size() < 3)
40         {
41             throw std::runtime_error("not enough gpio configs found");
42         }
43 
44         for (auto& gpio : buttonCfg.gpios)
45         {
46             if (gpio.name == DEBUG_CARD_PRESENT_GPIO)
47             {
48                 debugCardPresentGpio = gpio;
49                 break;
50             }
51         }
52 
53         gpioLineCount = buttonCfg.gpios.size() - 1;
54     }
55 
~SerialUartMux()56     ~SerialUartMux()
57     {
58         deInit();
59     }
60     void init() override;
getFormFactorName()61     static const std::string_view getFormFactorName()
62     {
63         return SERIAL_CONSOLE_SWITCH;
64     }
getDbusObjectPath()65     static const char* getDbusObjectPath()
66     {
67         return "NO_DBUS_OBJECT";
68     }
69 
70     void hostSelectorPositionChanged(sdbusplus::message_t& msg);
71     void configSerialConsoleMux(size_t position);
72     bool isOCPDebugCardPresent();
73 
handleEvent(sd_event_source *,int,uint32_t)74     void handleEvent(sd_event_source*, int, uint32_t) {}
75 
76   protected:
77     size_t gpioLineCount;
78     std::unique_ptr<sdbusplus::bus::match_t> hostPositionChanged;
79     GpioInfo debugCardPresentGpio;
80     std::unordered_map<size_t, size_t> serialUartMuxMap;
81 };
82