xref: /openbmc/hiomapd/control_dbus.c (revision 26558dbb00e439fb6ea18566361c0671ea6133f5)
155f4d6f9SAndrew Jeffery // SPDX-License-Identifier: Apache-2.0
255f4d6f9SAndrew Jeffery // Copyright (C) 2018 IBM Corp.
355f4d6f9SAndrew Jeffery #include <assert.h>
455f4d6f9SAndrew Jeffery #include <errno.h>
555f4d6f9SAndrew Jeffery #include <systemd/sd-bus.h>
655f4d6f9SAndrew Jeffery 
755f4d6f9SAndrew Jeffery #include "common.h"
855f4d6f9SAndrew Jeffery #include "dbus.h"
955f4d6f9SAndrew Jeffery #include "control_dbus.h"
10*26558dbbSAndrew Jeffery #include "mboxd.h"
1155f4d6f9SAndrew Jeffery 
1255f4d6f9SAndrew Jeffery typedef int (*control_action)(struct mbox_context *context);
1355f4d6f9SAndrew Jeffery 
1455f4d6f9SAndrew Jeffery static int control_dbus_directive(sd_bus_message *m, void *userdata,
1555f4d6f9SAndrew Jeffery 					sd_bus_error *ret_error,
1655f4d6f9SAndrew Jeffery 					control_action action)
1755f4d6f9SAndrew Jeffery {
1855f4d6f9SAndrew Jeffery 	struct mbox_context *context;
1955f4d6f9SAndrew Jeffery 	sd_bus_message *n;
2055f4d6f9SAndrew Jeffery 	int rc;
2155f4d6f9SAndrew Jeffery 
2255f4d6f9SAndrew Jeffery 	if (!action) {
2355f4d6f9SAndrew Jeffery 		MSG_ERR("No action provided\n");
2455f4d6f9SAndrew Jeffery 		return -EINVAL;
2555f4d6f9SAndrew Jeffery 	}
2655f4d6f9SAndrew Jeffery 
2755f4d6f9SAndrew Jeffery 	context = (struct mbox_context *) userdata;
2855f4d6f9SAndrew Jeffery 	if (!context) {
2955f4d6f9SAndrew Jeffery 		MSG_ERR("DBUS Internal Error\n");
3055f4d6f9SAndrew Jeffery 		return -EINVAL;
3155f4d6f9SAndrew Jeffery 	}
3255f4d6f9SAndrew Jeffery 
3355f4d6f9SAndrew Jeffery 	rc = action(context);
3455f4d6f9SAndrew Jeffery 	if (rc < 0) {
3555f4d6f9SAndrew Jeffery 		MSG_ERR("Action failed: %d\n", rc);
3655f4d6f9SAndrew Jeffery 		return rc;
3755f4d6f9SAndrew Jeffery 	}
3855f4d6f9SAndrew Jeffery 
3955f4d6f9SAndrew Jeffery 	rc = sd_bus_message_new_method_return(m, &n);
4055f4d6f9SAndrew Jeffery 	if (rc < 0) {
4155f4d6f9SAndrew Jeffery 		MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
4255f4d6f9SAndrew Jeffery 		return rc;
4355f4d6f9SAndrew Jeffery 	}
4455f4d6f9SAndrew Jeffery 
4555f4d6f9SAndrew Jeffery 	return sd_bus_send(NULL, n, NULL);
4655f4d6f9SAndrew Jeffery }
4755f4d6f9SAndrew Jeffery 
4855f4d6f9SAndrew Jeffery static int control_dbus_ping(sd_bus_message *m, void *userdata,
4955f4d6f9SAndrew Jeffery 				   sd_bus_error *ret_error)
5055f4d6f9SAndrew Jeffery {
5155f4d6f9SAndrew Jeffery 	return control_dbus_directive(m, userdata, ret_error, control_ping);
5255f4d6f9SAndrew Jeffery }
5355f4d6f9SAndrew Jeffery 
5455f4d6f9SAndrew Jeffery static int control_dbus_reset(sd_bus_message *m, void *userdata,
5555f4d6f9SAndrew Jeffery 				    sd_bus_error *ret_error)
5655f4d6f9SAndrew Jeffery {
5755f4d6f9SAndrew Jeffery 	return control_dbus_directive(m, userdata, ret_error, control_reset);
5855f4d6f9SAndrew Jeffery }
5955f4d6f9SAndrew Jeffery 
6055f4d6f9SAndrew Jeffery static int control_dbus_kill(sd_bus_message *m, void *userdata,
6155f4d6f9SAndrew Jeffery 				   sd_bus_error *ret_error)
6255f4d6f9SAndrew Jeffery {
6355f4d6f9SAndrew Jeffery 	return control_dbus_directive(m, userdata, ret_error, control_kill);
6455f4d6f9SAndrew Jeffery }
6555f4d6f9SAndrew Jeffery 
6655f4d6f9SAndrew Jeffery static int control_dbus_modified(sd_bus_message *m, void *userdata,
6755f4d6f9SAndrew Jeffery 				       sd_bus_error *ret_error)
6855f4d6f9SAndrew Jeffery {
6955f4d6f9SAndrew Jeffery 	return control_dbus_directive(m, userdata, ret_error, control_modified);
7055f4d6f9SAndrew Jeffery }
7155f4d6f9SAndrew Jeffery 
7255f4d6f9SAndrew Jeffery static int control_dbus_suspend(sd_bus_message *m, void *userdata,
7355f4d6f9SAndrew Jeffery 				      sd_bus_error *ret_error)
7455f4d6f9SAndrew Jeffery {
7555f4d6f9SAndrew Jeffery 	return control_dbus_directive(m, userdata, ret_error, control_suspend);
7655f4d6f9SAndrew Jeffery }
7755f4d6f9SAndrew Jeffery 
7855f4d6f9SAndrew Jeffery static int control_dbus_resume(sd_bus_message *m, void *userdata,
7955f4d6f9SAndrew Jeffery 				     sd_bus_error *ret_error)
8055f4d6f9SAndrew Jeffery {
8155f4d6f9SAndrew Jeffery 	struct mbox_context *context;
8255f4d6f9SAndrew Jeffery 	sd_bus_message *n;
8355f4d6f9SAndrew Jeffery 	bool modified;
8455f4d6f9SAndrew Jeffery 	int rc;
8555f4d6f9SAndrew Jeffery 
8655f4d6f9SAndrew Jeffery 	context = (struct mbox_context *) userdata;
8755f4d6f9SAndrew Jeffery 	if (!context) {
8855f4d6f9SAndrew Jeffery 		MSG_ERR("DBUS Internal Error\n");
8955f4d6f9SAndrew Jeffery 		return -EINVAL;
9055f4d6f9SAndrew Jeffery 	}
9155f4d6f9SAndrew Jeffery 
9255f4d6f9SAndrew Jeffery 	rc = sd_bus_message_read_basic(m, 'b', &modified);
9355f4d6f9SAndrew Jeffery 	if (rc < 0) {
9455f4d6f9SAndrew Jeffery 		MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
9555f4d6f9SAndrew Jeffery 		return rc;
9655f4d6f9SAndrew Jeffery 	}
9755f4d6f9SAndrew Jeffery 
9855f4d6f9SAndrew Jeffery 	rc = control_resume(context, modified);
9955f4d6f9SAndrew Jeffery 	if (rc < 0)
10055f4d6f9SAndrew Jeffery 		return rc;
10155f4d6f9SAndrew Jeffery 
10255f4d6f9SAndrew Jeffery 	rc = sd_bus_message_new_method_return(m, &n);
10355f4d6f9SAndrew Jeffery 	if (rc < 0) {
10455f4d6f9SAndrew Jeffery 		MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
10555f4d6f9SAndrew Jeffery 		return rc;
10655f4d6f9SAndrew Jeffery 	}
10755f4d6f9SAndrew Jeffery 
10855f4d6f9SAndrew Jeffery 	return sd_bus_send(NULL, n, NULL);
10955f4d6f9SAndrew Jeffery }
11055f4d6f9SAndrew Jeffery 
11155f4d6f9SAndrew Jeffery static int control_dbus_get_u8(sd_bus *bus, const char *path,
11255f4d6f9SAndrew Jeffery 			       const char *interface, const char *property,
11355f4d6f9SAndrew Jeffery 			       sd_bus_message *reply, void *userdata,
11455f4d6f9SAndrew Jeffery 			       sd_bus_error *ret_error)
11555f4d6f9SAndrew Jeffery {
11655f4d6f9SAndrew Jeffery 	struct mbox_context *context = userdata;
11755f4d6f9SAndrew Jeffery 	uint8_t value;
11855f4d6f9SAndrew Jeffery 
11955f4d6f9SAndrew Jeffery 	assert(!strcmp(MBOX_DBUS_OBJECT, path));
12055f4d6f9SAndrew Jeffery 
12155f4d6f9SAndrew Jeffery 	if (!strcmp("DaemonState", property)) {
12255f4d6f9SAndrew Jeffery 		value = control_daemon_state(context);
12355f4d6f9SAndrew Jeffery 	} else if (!strcmp("LpcState", property)) {
12455f4d6f9SAndrew Jeffery 		value = control_lpc_state(context);
12555f4d6f9SAndrew Jeffery 	} else {
12655f4d6f9SAndrew Jeffery 		MSG_ERR("Unknown DBus property: %s\n", property);
12755f4d6f9SAndrew Jeffery 		return -EINVAL;
12855f4d6f9SAndrew Jeffery 	}
12955f4d6f9SAndrew Jeffery 
13055f4d6f9SAndrew Jeffery 	return sd_bus_message_append(reply, "y", value);
13155f4d6f9SAndrew Jeffery }
13255f4d6f9SAndrew Jeffery 
13355f4d6f9SAndrew Jeffery static const sd_bus_vtable mboxd_vtable[] = {
13455f4d6f9SAndrew Jeffery 	SD_BUS_VTABLE_START(0),
13555f4d6f9SAndrew Jeffery 	SD_BUS_METHOD("Ping", NULL, NULL, &control_dbus_ping,
13655f4d6f9SAndrew Jeffery 		      SD_BUS_VTABLE_UNPRIVILEGED),
13755f4d6f9SAndrew Jeffery 	SD_BUS_METHOD("Reset", NULL, NULL, &control_dbus_reset,
13855f4d6f9SAndrew Jeffery 		      SD_BUS_VTABLE_UNPRIVILEGED),
13955f4d6f9SAndrew Jeffery 	SD_BUS_METHOD("Kill", NULL, NULL, &control_dbus_kill,
14055f4d6f9SAndrew Jeffery 		      SD_BUS_VTABLE_UNPRIVILEGED),
14155f4d6f9SAndrew Jeffery 	SD_BUS_METHOD("MarkFlashModified", NULL, NULL, &control_dbus_modified,
14255f4d6f9SAndrew Jeffery 		      SD_BUS_VTABLE_UNPRIVILEGED),
14355f4d6f9SAndrew Jeffery 	SD_BUS_METHOD("Suspend", NULL, NULL, &control_dbus_suspend,
14455f4d6f9SAndrew Jeffery 		      SD_BUS_VTABLE_UNPRIVILEGED),
14555f4d6f9SAndrew Jeffery 	SD_BUS_METHOD("Resume", "b", NULL, &control_dbus_resume,
14655f4d6f9SAndrew Jeffery 		      SD_BUS_VTABLE_UNPRIVILEGED),
14755f4d6f9SAndrew Jeffery 	SD_BUS_PROPERTY("DaemonState", "y", &control_dbus_get_u8, 0,
14855f4d6f9SAndrew Jeffery 		        SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
14955f4d6f9SAndrew Jeffery 	SD_BUS_PROPERTY("LpcState", "y", &control_dbus_get_u8, 0,
15055f4d6f9SAndrew Jeffery 		        SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
15155f4d6f9SAndrew Jeffery 	SD_BUS_VTABLE_END
15255f4d6f9SAndrew Jeffery };
15355f4d6f9SAndrew Jeffery 
15455f4d6f9SAndrew Jeffery int control_dbus_init(struct mbox_context *context)
15555f4d6f9SAndrew Jeffery {
15655f4d6f9SAndrew Jeffery 	return sd_bus_add_object_vtable(context->bus, NULL,
15755f4d6f9SAndrew Jeffery 					MBOX_DBUS_OBJECT,
15855f4d6f9SAndrew Jeffery 					MBOX_DBUS_CONTROL_IFACE,
15955f4d6f9SAndrew Jeffery 					mboxd_vtable, context);
16055f4d6f9SAndrew Jeffery }
16155f4d6f9SAndrew Jeffery 
16255f4d6f9SAndrew Jeffery #define __unused __attribute__((unused))
16355f4d6f9SAndrew Jeffery void control_dbus_free(struct mbox_context *context __unused)
16455f4d6f9SAndrew Jeffery {
16555f4d6f9SAndrew Jeffery 	return;
16655f4d6f9SAndrew Jeffery }
167