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