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