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