summaryrefslogtreecommitdiffstats
path: root/control_dbus.c
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2018-08-06 12:26:44 +0930
committerAndrew Jeffery <andrew@aj.id.au>2018-09-05 17:44:24 +0930
commit55f4d6f9117f692a71d5bdd51a48dc3b4e553b84 (patch)
tree14d0f3e64b59d0afaa05f618dd82fff0eb52d97c /control_dbus.c
parent68023074e38569129c6239bba5785d2513c507c8 (diff)
downloadphosphor-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.c166
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;
+}
OpenPOWER on IntegriCloud