1 #pragma once 2 3 #include "main.hpp" 4 #include "sol/sol_manager.hpp" 5 6 #include <systemd/sd-event.h> 7 8 #include <boost/asio/io_context.hpp> 9 #include <sdbusplus/asio/connection.hpp> 10 11 #include <chrono> 12 #include <map> 13 #include <string> 14 15 namespace ipmi 16 { 17 namespace rmcpp 18 { 19 constexpr uint16_t defaultPort = 623; 20 } // namespace rmcpp 21 } // namespace ipmi 22 23 namespace eventloop 24 { 25 using DbusObjectPath = std::string; 26 using DbusService = std::string; 27 using DbusInterface = std::string; 28 using ObjectTree = 29 std::map<DbusObjectPath, std::map<DbusService, std::vector<DbusInterface>>>; 30 using Value = std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, 31 int64_t, uint64_t, double, std::string>; 32 // VLANs are a 12-bit value 33 constexpr uint16_t VLAN_VALUE_MASK = 0x0fff; 34 constexpr auto MAPPER_BUS_NAME = "xyz.openbmc_project.ObjectMapper"; 35 constexpr auto MAPPER_OBJ = "/xyz/openbmc_project/object_mapper"; 36 constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper"; 37 constexpr auto PATH_ROOT = "/xyz/openbmc_project/network"; 38 constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN"; 39 constexpr auto INTF_ETHERNET = "xyz.openbmc_project.Network.EthernetInterface"; 40 constexpr auto METHOD_GET = "Get"; 41 constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties"; 42 43 class EventLoop 44 { 45 private: 46 struct Private 47 {}; 48 49 public: EventLoop(std::shared_ptr<boost::asio::io_context> & io,const Private &)50 EventLoop(std::shared_ptr<boost::asio::io_context>& io, const Private&) : 51 io(io) 52 {} 53 EventLoop() = delete; 54 ~EventLoop() = default; 55 EventLoop(const EventLoop&) = delete; 56 EventLoop& operator=(const EventLoop&) = delete; 57 EventLoop(EventLoop&&) = delete; 58 EventLoop& operator=(EventLoop&&) = delete; 59 60 /** 61 * @brief Get a reference to the singleton EventLoop 62 * 63 * @return EventLoop reference 64 */ get()65 static EventLoop& get() 66 { 67 static std::shared_ptr<EventLoop> ptr = nullptr; 68 if (!ptr) 69 { 70 std::shared_ptr<boost::asio::io_context> io = getIo(); 71 ptr = std::make_shared<EventLoop>(io, Private()); 72 } 73 return *ptr; 74 } 75 76 /** @brief Initialise the event loop and add the handler for incoming 77 * IPMI packets. 78 * 79 * @return EXIT_SUCCESS on success and EXIT_FAILURE on failure. 80 */ 81 int startEventLoop(); 82 83 /** @brief Set up the socket (if systemd has not already) and 84 * make sure that the bus name matches the specified channel 85 */ 86 int setupSocket(std::shared_ptr<sdbusplus::asio::connection>& bus, 87 std::string iface, 88 uint16_t reqPort = ipmi::rmcpp::defaultPort); 89 90 /** @brief set up boost::asio signal handling */ 91 void setupSignal(); 92 93 private: 94 /** @brief async handler for incoming udp packets */ 95 void handleRmcpPacket(); 96 97 /** @brief register the async handler for incoming udp packets */ 98 void startRmcpReceive(); 99 100 /** @brief get vlanid */ 101 int getVLANID(const std::string channel); 102 103 /** @brief boost::asio io context to run with 104 */ 105 std::shared_ptr<boost::asio::io_context> io; 106 107 /** @brief boost::asio udp socket 108 */ 109 std::shared_ptr<boost::asio::ip::udp::socket> udpSocket = nullptr; 110 }; 111 112 } // namespace eventloop 113