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