blob: 50a6cadbdd0ee1cfa9cdf83590909eb5cbb4d8ec [file] [log] [blame]
#include <algorithm>
#include <sdbusplus/server.hpp>
#include <sdbusplus/exception.hpp>
#include <${"/".join(interface.name.split('.') + [ 'server.hpp' ])}>
% for m in interface.methods:
${ m.cpp_prototype(loader, interface=interface, ptype='callback-cpp-includes') }
% endfor
<%
namespaces = interface.name.split('.')
classname = namespaces.pop()
def interface_instance():
return "_".join(interface.name.split('.') + ['interface'])
%>
namespace sdbusplus
{
% for s in namespaces:
namespace ${s}
{
% endfor
namespace server
{
${classname}::${classname}(bus::bus& bus, const char* path)
: _${interface_instance()}(
bus, path, _interface, _vtable, this)
{
}
% for m in interface.methods:
${ m.cpp_prototype(loader, interface=interface, ptype='callback-cpp') }
% endfor
% for s in interface.signals:
${ s.cpp_prototype(loader, interface=interface, ptype='callback-cpp') }
% endfor
% for p in interface.properties:
auto ${classname}::${p.camelCase}() const ->
${p.cppTypeParam(interface.name)}
{
return _${p.camelCase};
}
int ${classname}::_callback_get_${p.name}(
sd_bus* bus, const char* path, const char* interface,
const char* property, sd_bus_message* reply, void* context,
sd_bus_error* error)
{
using sdbusplus::server::binding::details::convertForMessage;
try
{
auto m = message::message(sd_bus_message_ref(reply));
auto o = static_cast<${classname}*>(context);
m.append(convertForMessage(o->${p.camelCase}()));
}
catch(sdbusplus::internal_exception_t& e)
{
sd_bus_error_set_const(error, e.name(), e.description());
return -EINVAL;
}
return true;
}
auto ${classname}::${p.camelCase}(${p.cppTypeParam(interface.name)} value) ->
${p.cppTypeParam(interface.name)}
{
if (_${p.camelCase} != value)
{
_${p.camelCase} = value;
_${interface_instance()}.property_changed("${p.name}");
}
return _${p.camelCase};
}
int ${classname}::_callback_set_${p.name}(
sd_bus* bus, const char* path, const char* interface,
const char* property, sd_bus_message* value, void* context,
sd_bus_error* error)
{
try
{
auto m = message::message(sd_bus_message_ref(value));
auto o = static_cast<${classname}*>(context);
${p.cppTypeMessage(interface.name)} v{};
m.read(v);
% if p.is_enum():
o->${p.camelCase}(${p.enum_namespace(interface.name)}\
convert${p.enum_name(interface.name)}FromString(v));
% else:
o->${p.camelCase}(v);
% endif
}
catch(sdbusplus::internal_exception_t& e)
{
sd_bus_error_set_const(error, e.name(), e.description());
return -EINVAL;
}
return true;
}
namespace details
{
namespace ${classname}
{
static const auto _property_${p.name} =
utility::tuple_to_array(message::types::type_id<
${p.cppTypeMessage(interface.name)}>());
}
}
% endfor
% for e in interface.enums:
namespace
{
/** String to enum mapping for ${classname}::${e.name} */
static const std::tuple<const char*, ${classname}::${e.name}> \
mapping${classname}${e.name}[] =
{
% for v in e.values:
std::make_tuple( "${interface.name}.${e.name}.${v.name}", \
${classname}::${e.name}::${v.name} ),
% endfor
};
} // anonymous namespace
auto ${classname}::convert${e.name}FromString(std::string& s) ->
${e.name}
{
auto i = std::find_if(
std::begin(mapping${classname}${e.name}),
std::end(mapping${classname}${e.name}),
[&s](auto& e){ return 0 == strcmp(s.c_str(), std::get<0>(e)); } );
if (std::end(mapping${classname}${e.name}) == i)
{
throw sdbusplus::exception::InvalidEnumString();
}
else
{
return std::get<1>(*i);
}
}
std::string convertForMessage(${classname}::${e.name} v)
{
auto i = std::find_if(
std::begin(mapping${classname}${e.name}),
std::end(mapping${classname}${e.name}),
[v](auto& e){ return v == std::get<1>(e); });
return std::get<0>(*i);
}
% endfor
const vtable::vtable_t ${classname}::_vtable[] = {
vtable::start(),
% for m in interface.methods:
${ m.cpp_prototype(loader, interface=interface, ptype='vtable') }
% endfor
% for s in interface.signals:
${ s.cpp_prototype(loader, interface=interface, ptype='vtable') }
% endfor
% for p in interface.properties:
vtable::property("${p.name}",
details::${classname}::_property_${p.name}
.data(),
_callback_get_${p.name},
_callback_set_${p.name},
vtable::property_::emits_change),
% endfor
vtable::end()
};
} // namespace server
% for s in reversed(namespaces):
} // namespace ${s}
% endfor
} // namespace sdbusplus