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