xref: /openbmc/hiomapd/control_dbus.c (revision f1e547c7)
1 // 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 "mboxd.h"
11 
12 typedef int (*control_action)(struct mbox_context *context);
13 
14 static 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 
48 static 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 
54 static 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 
60 static 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 
66 static 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 
72 static 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 
78 static 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 
111 static 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 
133 static 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 
154 int 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))
163 void control_dbus_free(struct mbox_context *context __unused)
164 {
165 	return;
166 }
167