1#pragma once
2#include <limits>
3#include <map>
4#include <sdbusplus/sdbus.hpp>
5#include <sdbusplus/server.hpp>
6#include <string>
7#include <systemd/sd-bus.h>
8
9% for h in interface.cpp_includes():
10#include <${h}>
11% endfor
12#include <${interface.headerFile()}>
13
14namespace sdbusplus::server::${interface.cppNamespace()}
15{
16
17class ${interface.classname} :
18    public sdbusplus::common::${interface.cppNamespacedClass()}
19{
20    public:
21        /* Define all of the basic class operations:
22         *     Not allowed:
23         *         - Default constructor to avoid nullptrs.
24         *         - Copy operations due to internal unique_ptr.
25         *         - Move operations due to 'this' being registered as the
26         *           'context' with sdbus.
27         *     Allowed:
28         *         - Destructor.
29         */
30        ${interface.classname}() = delete;
31        ${interface.classname}(const ${interface.classname}&) = delete;
32        ${interface.classname}& operator=(const ${interface.classname}&) = delete;
33        ${interface.classname}(${interface.classname}&&) = delete;
34        ${interface.classname}& operator=(${interface.classname}&&) = delete;
35        virtual ~${interface.classname}() = default;
36
37        /** @brief Constructor to put object onto bus at a dbus path.
38         *  @param[in] bus - Bus to attach to.
39         *  @param[in] path - Path to attach at.
40         */
41        ${interface.classname}(bus_t& bus, const char* path) :
42            _${interface.joinedName("_", "interface")}(
43                bus, path, interface, _vtable, this),
44            _sdbusplus_bus(bus) {}
45
46    % if interface.properties:
47        /** @brief Constructor to initialize the object from a map of
48         *         properties.
49         *
50         *  @param[in] bus - Bus to attach to.
51         *  @param[in] path - Path to attach at.
52         *  @param[in] vals - Map of property name to value for initialization.
53         */
54        ${interface.classname}(bus_t& bus, const char* path,
55                     const std::map<std::string, PropertiesVariant>& vals,
56                     bool skipSignal = false) :
57            ${interface.classname}(bus, path)
58        {
59            for (const auto& v : vals)
60            {
61                setPropertyByName(v.first, v.second, skipSignal);
62            }
63        }
64
65    % endif
66    % for m in interface.methods:
67${ m.cpp_prototype(loader, interface=interface, ptype='header') }
68    % endfor
69\
70    % for s in interface.signals:
71${ s.cpp_prototype(loader, interface=interface, ptype='header') }
72    % endfor
73\
74    % for p in interface.properties:
75        /** Get value of ${p.name} */
76        virtual ${p.cppTypeParam(interface.name)} ${p.camelCase}() const;
77        /** Set value of ${p.name} with option to skip sending signal */
78        virtual ${p.cppTypeParam(interface.name)} \
79${p.camelCase}(${p.cppTypeParam(interface.name)} value,
80               bool skipSignal);
81        /** Set value of ${p.name} */
82        virtual ${p.cppTypeParam(interface.name)} \
83${p.camelCase}(${p.cppTypeParam(interface.name)} value);
84    % endfor
85
86    % if interface.properties:
87        /** @brief Sets a property by name.
88         *  @param[in] _name - A string representation of the property name.
89         *  @param[in] val - A variant containing the value to set.
90         */
91        void setPropertyByName(const std::string& _name,
92                               const PropertiesVariant& val,
93                               bool skipSignal = false);
94
95        /** @brief Gets a property by name.
96         *  @param[in] _name - A string representation of the property name.
97         *  @return - A variant containing the value of the property.
98         */
99        PropertiesVariant getPropertyByName(const std::string& _name);
100
101    % endif
102
103
104        /** @brief Emit interface added */
105        void emit_added()
106        {
107            _${interface.joinedName("_", "interface")}.emit_added();
108        }
109
110        /** @brief Emit interface removed */
111        void emit_removed()
112        {
113            _${interface.joinedName("_", "interface")}.emit_removed();
114        }
115
116        /** @return the bus instance */
117        bus_t& get_bus()
118        {
119            return  _sdbusplus_bus;
120        }
121
122    private:
123    % for m in interface.methods:
124${ m.cpp_prototype(loader, interface=interface, ptype='callback-header') }
125    % endfor
126
127    % for p in interface.properties:
128        /** @brief sd-bus callback for get-property '${p.name}' */
129        static int _callback_get_${p.name}(
130            sd_bus*, const char*, const char*, const char*,
131            sd_bus_message*, void*, sd_bus_error*);
132        % if 'const' not in p.flags and 'readonly' not in p.flags:
133        /** @brief sd-bus callback for set-property '${p.name}' */
134        static int _callback_set_${p.name}(
135            sd_bus*, const char*, const char*, const char*,
136            sd_bus_message*, void*, sd_bus_error*);
137        % endif
138
139    % endfor
140        static const vtable_t _vtable[];
141        sdbusplus::server::interface_t
142                _${interface.joinedName("_", "interface")};
143        bus_t&  _sdbusplus_bus;
144    % for p in interface.properties:
145        % if p.defaultValue is not None:
146        ${p.cppTypeParam(interface.name)} _${p.camelCase} = \
147            % if p.is_enum():
148${p.cppTypeParam(interface.name)}::\
149            % endif
150${p.defaultValue};
151        % else:
152        ${p.cppTypeParam(interface.name)} _${p.camelCase}{};
153        % endif
154
155    % endfor
156
157};
158
159} // namespace sdbusplus::server::${interface.cppNamespace()}
160
161#ifndef SDBUSPP_REMOVE_DEPRECATED_NAMESPACE
162namespace sdbusplus::${interface.old_cppNamespace()} {
163
164using sdbusplus::server::${interface.cppNamespacedClass()};
165    % if interface.enums:
166using sdbusplus::common::${interface.cppNamespace()}::convertForMessage;
167    % endif
168
169} // namespace sdbusplus::${interface.old_cppNamespace()}
170#endif
171