1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter Stef Walter <stefw@redhat.com>
b742179ac0790068380618ab72a06af18544f09cPavel Březina Pavel Březina <pbrezina@redhat.com>
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter Copyright (C) 2014 Red Hat
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter This program is free software; you can redistribute it and/or modify
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter it under the terms of the GNU General Public License as published by
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter the Free Software Foundation; either version 3 of the License, or
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter (at your option) any later version.
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter This program is distributed in the hope that it will be useful,
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter but WITHOUT ANY WARRANTY; without even the implied warranty of
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter GNU General Public License for more details.
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter You should have received a copy of the GNU General Public License
1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4Stef Walter along with this program. If not, see <http://www.gnu.org/licenses/>.
b742179ac0790068380618ab72a06af18544f09cPavel Březina#define CHECK_SIGNATURE_OR_FAIL(req, error, label, exp) do { \
b742179ac0790068380618ab72a06af18544f09cPavel Březina const char *__sig; \
b742179ac0790068380618ab72a06af18544f09cPavel Březina __sig = dbus_message_get_signature(req->message); \
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(req, DBUS_ERROR_INVALID_ARGS, \
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Invalid arguments: expected \"%s\", got \"%s\"", exp, __sig); \
b742179ac0790068380618ab72a06af18544f09cPavel Březina struct sbus_vtable vtable; /* derive from sbus_vtable */
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get(struct sbus_request *sbus_req, void *pvt);
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_set(struct sbus_request *sbus_req, void *pvt);
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get_all(struct sbus_request *sbus_req, void *pvt);
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.Get */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta get_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta get_args_out[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.Set */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta set_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Properties.GetAll */
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta getall_args_in[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_arg_meta getall_args_out[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_method_meta iface_methods[] = {
b742179ac0790068380618ab72a06af18544f09cPavel Březina static const struct sbus_interface_meta iface_meta = {
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březinasbus_properties_subreq(struct sbus_request *sbus_req,
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* Create new sbus_request to so it contain given interface. The
b742179ac0790068380618ab72a06af18544f09cPavel Březina * old sbus_request talloc context will be attached to this new one
b742179ac0790068380618ab72a06af18544f09cPavel Březina * so it is freed together. */
b742179ac0790068380618ab72a06af18544f09cPavel Březina sbus_subreq = sbus_new_request(sbus_req->conn, iface, sbus_req->message);
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ss");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* request was handled */
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find property handler */
b742179ac0790068380618ab72a06af18544f09cPavel Březina prop = sbus_meta_find_property(iface->vtable->meta, property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown property");
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (!(prop->flags & SBUS_PROPERTY_READABLE)) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_ACCESS_DENIED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Property is not readable");
b742179ac0790068380618ab72a06af18544f09cPavel Březina handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_get);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Getter is not implemented");
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_subreq = sbus_properties_subreq(sbus_req, iface);
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
b742179ac0790068380618ab72a06af18544f09cPavel Březina * We don't implement any handlers for setters yet. This code is for future
b742179ac0790068380618ab72a06af18544f09cPavel Březina * use and it is likely it will need some changes.
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_set(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ssv");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* get interface and property */
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_init(sbus_req->message, &iter);
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_get_basic(&iter, &interface_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_get_basic(&iter, &property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find property handler */
b742179ac0790068380618ab72a06af18544f09cPavel Březina prop = sbus_meta_find_property(iface->vtable->meta, property_name);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown property");
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (!(prop->flags & SBUS_PROPERTY_WRITABLE)) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_ACCESS_DENIED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Property is not writable");
b742179ac0790068380618ab72a06af18544f09cPavel Březina handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_set);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Setter is not implemented");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* check variant type */
b742179ac0790068380618ab72a06af18544f09cPavel Březina dbus_message_iter_recurse(&iter, &iter_variant);
b742179ac0790068380618ab72a06af18544f09cPavel Březina variant_sig = dbus_message_iter_get_signature(&iter_variant);
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_INVALID_ARGS,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Invalid data type for property");
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_subreq = sbus_properties_subreq(sbus_req, iface);
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_request_invoke_or_finish(sbus_subreq, handler_fn,
b742179ac0790068380618ab72a06af18544f09cPavel Březina return sbus_request_fail_and_finish(sbus_req, error);
b742179ac0790068380618ab72a06af18544f09cPavel Březinastatic int sbus_properties_get_all(struct sbus_request *sbus_req, void *pvt)
b742179ac0790068380618ab72a06af18544f09cPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
b742179ac0790068380618ab72a06af18544f09cPavel Březina CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "s");
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* request was handled */
b742179ac0790068380618ab72a06af18544f09cPavel Březina /* find interface */
b742179ac0790068380618ab72a06af18544f09cPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path,
b742179ac0790068380618ab72a06af18544f09cPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE,
b742179ac0790068380618ab72a06af18544f09cPavel Březina "Unknown interface");
df4e1db5d41c903ae57fd880acc76a0ad84aa7b2Pavel Březina sbus_subreq = sbus_properties_subreq(sbus_req, iface);
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina if (iface->vtable->meta->invoker_get_all == NULL) {
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "No get all invoker set,"
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina "using the default one\n");
c5184e9eeb0fd0bc4749677d2f74256515199b46Pavel Březina iface->vtable->meta->invoker_get_all(sbus_subreq);