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