diff options
author | Andrew Jeffery <andrew@aj.id.au> | 2018-08-06 12:26:44 +0930 |
---|---|---|
committer | Andrew Jeffery <andrew@aj.id.au> | 2018-09-05 17:44:24 +0930 |
commit | 55f4d6f9117f692a71d5bdd51a48dc3b4e553b84 (patch) | |
tree | 14d0f3e64b59d0afaa05f618dd82fff0eb52d97c /control_dbus.c | |
parent | 68023074e38569129c6239bba5785d2513c507c8 (diff) | |
download | phosphor-mboxbridge-55f4d6f9117f692a71d5bdd51a48dc3b4e553b84.tar.gz phosphor-mboxbridge-55f4d6f9117f692a71d5bdd51a48dc3b4e553b84.zip |
dbus: Use new bus name, object and interface
The new interface is a more typical use of DBus, exposing multiple
methods for the functions that are available on the object. The legacy
interface by comparison exposed only one method whose arguments selected
sub-commands to be executed. The legacy approach is not terribly
discoverable and leads to a lack of clarity in the client code. The
legacy approach also obscured the implementation with its use of `struct
mbox_dbus_msg`. The new interface wraps around the existing helpers and
so also deals with `struct mbox_dbus_msg`, but this can at least be
removed in the future.
Change-Id: I7113ed8fd2324bf3fb049d8d20acb3fd7fba6de3
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Diffstat (limited to 'control_dbus.c')
-rw-r--r-- | control_dbus.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/control_dbus.c b/control_dbus.c new file mode 100644 index 0000000..c970b8f --- /dev/null +++ b/control_dbus.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2018 IBM Corp. +#include <assert.h> +#include <errno.h> +#include <systemd/sd-bus.h> + +#include "common.h" +#include "dbus.h" +#include "control_dbus.h" +#include "mbox.h" + +typedef int (*control_action)(struct mbox_context *context); + +static int control_dbus_directive(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error, + control_action action) +{ + struct mbox_context *context; + sd_bus_message *n; + int rc; + + if (!action) { + MSG_ERR("No action provided\n"); + return -EINVAL; + } + + context = (struct mbox_context *) userdata; + if (!context) { + MSG_ERR("DBUS Internal Error\n"); + return -EINVAL; + } + + rc = action(context); + if (rc < 0) { + MSG_ERR("Action failed: %d\n", rc); + return rc; + } + + rc = sd_bus_message_new_method_return(m, &n); + if (rc < 0) { + MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc); + return rc; + } + + return sd_bus_send(NULL, n, NULL); +} + +static int control_dbus_ping(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error) +{ + return control_dbus_directive(m, userdata, ret_error, control_ping); +} + +static int control_dbus_reset(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error) +{ + return control_dbus_directive(m, userdata, ret_error, control_reset); +} + +static int control_dbus_kill(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error) +{ + return control_dbus_directive(m, userdata, ret_error, control_kill); +} + +static int control_dbus_modified(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error) +{ + return control_dbus_directive(m, userdata, ret_error, control_modified); +} + +static int control_dbus_suspend(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error) +{ + return control_dbus_directive(m, userdata, ret_error, control_suspend); +} + +static int control_dbus_resume(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error) +{ + struct mbox_context *context; + sd_bus_message *n; + bool modified; + int rc; + + context = (struct mbox_context *) userdata; + if (!context) { + MSG_ERR("DBUS Internal Error\n"); + return -EINVAL; + } + + rc = sd_bus_message_read_basic(m, 'b', &modified); + if (rc < 0) { + MSG_ERR("DBUS error reading message: %s\n", strerror(-rc)); + return rc; + } + + rc = control_resume(context, modified); + if (rc < 0) + return rc; + + rc = sd_bus_message_new_method_return(m, &n); + if (rc < 0) { + MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc); + return rc; + } + + return sd_bus_send(NULL, n, NULL); +} + +static int control_dbus_get_u8(sd_bus *bus, const char *path, + const char *interface, const char *property, + sd_bus_message *reply, void *userdata, + sd_bus_error *ret_error) +{ + struct mbox_context *context = userdata; + uint8_t value; + + assert(!strcmp(MBOX_DBUS_OBJECT, path)); + + if (!strcmp("DaemonState", property)) { + value = control_daemon_state(context); + } else if (!strcmp("LpcState", property)) { + value = control_lpc_state(context); + } else { + MSG_ERR("Unknown DBus property: %s\n", property); + return -EINVAL; + } + + return sd_bus_message_append(reply, "y", value); +} + +static const sd_bus_vtable mboxd_vtable[] = { + SD_BUS_VTABLE_START(0), + SD_BUS_METHOD("Ping", NULL, NULL, &control_dbus_ping, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Reset", NULL, NULL, &control_dbus_reset, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Kill", NULL, NULL, &control_dbus_kill, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("MarkFlashModified", NULL, NULL, &control_dbus_modified, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Suspend", NULL, NULL, &control_dbus_suspend, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Resume", "b", NULL, &control_dbus_resume, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_PROPERTY("DaemonState", "y", &control_dbus_get_u8, 0, + SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("LpcState", "y", &control_dbus_get_u8, 0, + SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_VTABLE_END +}; + +int control_dbus_init(struct mbox_context *context) +{ + return sd_bus_add_object_vtable(context->bus, NULL, + MBOX_DBUS_OBJECT, + MBOX_DBUS_CONTROL_IFACE, + mboxd_vtable, context); +} + +#define __unused __attribute__((unused)) +void control_dbus_free(struct mbox_context *context __unused) +{ + return; +} |