blob: c970b8fc8089e45c0743a18fb4c6101b2a6cce4d [file] [log] [blame]
Andrew Jeffery55f4d6f2018-08-06 12:26:44 +09301// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2018 IBM Corp.
3#include <assert.h>
4#include <errno.h>
5#include <systemd/sd-bus.h>
6
7#include "common.h"
8#include "dbus.h"
9#include "control_dbus.h"
10#include "mbox.h"
11
12typedef int (*control_action)(struct mbox_context *context);
13
14static int control_dbus_directive(sd_bus_message *m, void *userdata,
15 sd_bus_error *ret_error,
16 control_action action)
17{
18 struct mbox_context *context;
19 sd_bus_message *n;
20 int rc;
21
22 if (!action) {
23 MSG_ERR("No action provided\n");
24 return -EINVAL;
25 }
26
27 context = (struct mbox_context *) userdata;
28 if (!context) {
29 MSG_ERR("DBUS Internal Error\n");
30 return -EINVAL;
31 }
32
33 rc = action(context);
34 if (rc < 0) {
35 MSG_ERR("Action failed: %d\n", rc);
36 return rc;
37 }
38
39 rc = sd_bus_message_new_method_return(m, &n);
40 if (rc < 0) {
41 MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
42 return rc;
43 }
44
45 return sd_bus_send(NULL, n, NULL);
46}
47
48static int control_dbus_ping(sd_bus_message *m, void *userdata,
49 sd_bus_error *ret_error)
50{
51 return control_dbus_directive(m, userdata, ret_error, control_ping);
52}
53
54static int control_dbus_reset(sd_bus_message *m, void *userdata,
55 sd_bus_error *ret_error)
56{
57 return control_dbus_directive(m, userdata, ret_error, control_reset);
58}
59
60static int control_dbus_kill(sd_bus_message *m, void *userdata,
61 sd_bus_error *ret_error)
62{
63 return control_dbus_directive(m, userdata, ret_error, control_kill);
64}
65
66static int control_dbus_modified(sd_bus_message *m, void *userdata,
67 sd_bus_error *ret_error)
68{
69 return control_dbus_directive(m, userdata, ret_error, control_modified);
70}
71
72static int control_dbus_suspend(sd_bus_message *m, void *userdata,
73 sd_bus_error *ret_error)
74{
75 return control_dbus_directive(m, userdata, ret_error, control_suspend);
76}
77
78static int control_dbus_resume(sd_bus_message *m, void *userdata,
79 sd_bus_error *ret_error)
80{
81 struct mbox_context *context;
82 sd_bus_message *n;
83 bool modified;
84 int rc;
85
86 context = (struct mbox_context *) userdata;
87 if (!context) {
88 MSG_ERR("DBUS Internal Error\n");
89 return -EINVAL;
90 }
91
92 rc = sd_bus_message_read_basic(m, 'b', &modified);
93 if (rc < 0) {
94 MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
95 return rc;
96 }
97
98 rc = control_resume(context, modified);
99 if (rc < 0)
100 return rc;
101
102 rc = sd_bus_message_new_method_return(m, &n);
103 if (rc < 0) {
104 MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
105 return rc;
106 }
107
108 return sd_bus_send(NULL, n, NULL);
109}
110
111static int control_dbus_get_u8(sd_bus *bus, const char *path,
112 const char *interface, const char *property,
113 sd_bus_message *reply, void *userdata,
114 sd_bus_error *ret_error)
115{
116 struct mbox_context *context = userdata;
117 uint8_t value;
118
119 assert(!strcmp(MBOX_DBUS_OBJECT, path));
120
121 if (!strcmp("DaemonState", property)) {
122 value = control_daemon_state(context);
123 } else if (!strcmp("LpcState", property)) {
124 value = control_lpc_state(context);
125 } else {
126 MSG_ERR("Unknown DBus property: %s\n", property);
127 return -EINVAL;
128 }
129
130 return sd_bus_message_append(reply, "y", value);
131}
132
133static const sd_bus_vtable mboxd_vtable[] = {
134 SD_BUS_VTABLE_START(0),
135 SD_BUS_METHOD("Ping", NULL, NULL, &control_dbus_ping,
136 SD_BUS_VTABLE_UNPRIVILEGED),
137 SD_BUS_METHOD("Reset", NULL, NULL, &control_dbus_reset,
138 SD_BUS_VTABLE_UNPRIVILEGED),
139 SD_BUS_METHOD("Kill", NULL, NULL, &control_dbus_kill,
140 SD_BUS_VTABLE_UNPRIVILEGED),
141 SD_BUS_METHOD("MarkFlashModified", NULL, NULL, &control_dbus_modified,
142 SD_BUS_VTABLE_UNPRIVILEGED),
143 SD_BUS_METHOD("Suspend", NULL, NULL, &control_dbus_suspend,
144 SD_BUS_VTABLE_UNPRIVILEGED),
145 SD_BUS_METHOD("Resume", "b", NULL, &control_dbus_resume,
146 SD_BUS_VTABLE_UNPRIVILEGED),
147 SD_BUS_PROPERTY("DaemonState", "y", &control_dbus_get_u8, 0,
148 SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
149 SD_BUS_PROPERTY("LpcState", "y", &control_dbus_get_u8, 0,
150 SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
151 SD_BUS_VTABLE_END
152};
153
154int control_dbus_init(struct mbox_context *context)
155{
156 return sd_bus_add_object_vtable(context->bus, NULL,
157 MBOX_DBUS_OBJECT,
158 MBOX_DBUS_CONTROL_IFACE,
159 mboxd_vtable, context);
160}
161
162#define __unused __attribute__((unused))
163void control_dbus_free(struct mbox_context *context __unused)
164{
165 return;
166}