예제 #1
0
/* called when the object for the service is called */
static int api_dbus_server_on_object_called(sd_bus_message *message, void *userdata, sd_bus_error *ret_error)
{
	int rc;
	const char *method;
	const char *uuid;
	struct dbus_req *dreq;
	struct api_dbus *api = userdata;
	struct afb_req areq;
	uint32_t flags;

	/* check the interface */
	if (strcmp(sd_bus_message_get_interface(message), api->name) != 0)
		return 0;

	/* get the method */
	method = sd_bus_message_get_member(message);

	/* create the request */
	dreq = calloc(1 , sizeof *dreq);
	if (dreq == NULL) {
		sd_bus_reply_method_errorf(message, SD_BUS_ERROR_NO_MEMORY, "out of memory");
		return 1;
	}

	/* get the data */
	rc = sd_bus_message_read(message, "ssu", &dreq->request, &uuid, &flags);
	if (rc < 0) {
		sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_SIGNATURE, "invalid signature");
		free(dreq);
		return 1;
	}

	/* connect to the context */
	if (afb_context_connect(&dreq->context, uuid, NULL) < 0) {
		sd_bus_reply_method_errorf(message, SD_BUS_ERROR_NO_MEMORY, "out of memory");
		free(dreq);
		return 1;
	}

	/* fulfill the request and emit it */
	dreq->context.flags = flags;
	dreq->message = sd_bus_message_ref(message);
	dreq->json = NULL;
	dreq->refcount = 1;
	areq.itf = &dbus_req_itf;
	areq.closure = dreq;
	afb_apis_call_(areq, &dreq->context, api->api, method);
	dbus_req_unref(dreq);
	return 1;
}
예제 #2
0
static int match_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
        log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m)));
        return 0;
}
예제 #3
0
static int server(sd_bus *bus) {
        int r;
        bool client1_gone = false, client2_gone = false;

        while (!client1_gone || !client2_gone) {
                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
                pid_t pid = 0;
                const char *label = NULL;

                r = sd_bus_process(bus, &m);
                if (r < 0) {
                        log_error_errno(r, "Failed to process requests: %m");
                        goto fail;
                }

                if (r == 0) {
                        r = sd_bus_wait(bus, (uint64_t) -1);
                        if (r < 0) {
                                log_error_errno(r, "Failed to wait: %m");
                                goto fail;
                        }

                        continue;
                }

                if (!m)
                        continue;

                sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid);
                sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label);
                log_info("Got message! member=%s pid="PID_FMT" label=%s",
                         strna(sd_bus_message_get_member(m)),
                         pid,
                         strna(label));
                /* bus_message_dump(m); */
                /* sd_bus_message_rewind(m, true); */

                if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
                        const char *hello;
                        _cleanup_free_ char *lowercase = NULL;

                        r = sd_bus_message_read(m, "s", &hello);
                        if (r < 0) {
                                log_error_errno(r, "Failed to get parameter: %m");
                                goto fail;
                        }

                        lowercase = strdup(hello);
                        if (!lowercase) {
                                r = log_oom();
                                goto fail;
                        }

                        ascii_strlower(lowercase);

                        r = sd_bus_reply_method_return(m, "s", lowercase);
                        if (r < 0) {
                                log_error_errno(r, "Failed to send reply: %m");
                                goto fail;
                        }
                } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {

                        r = sd_bus_reply_method_return(m, NULL);
                        if (r < 0) {
                                log_error_errno(r, "Failed to send reply: %m");
                                goto fail;
                        }

                        client1_gone = true;
                } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) {

                        r = sd_bus_reply_method_return(m, NULL);
                        if (r < 0) {
                                log_error_errno(r, "Failed to send reply: %m");
                                goto fail;
                        }

                        client2_gone = true;
                } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {

                        sleep(1);

                        r = sd_bus_reply_method_return(m, NULL);
                        if (r < 0) {
                                log_error_errno(r, "Failed to send reply: %m");
                                goto fail;
                        }

                } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "FileDescriptor")) {
                        int fd;
                        static const char x = 'X';

                        r = sd_bus_message_read(m, "h", &fd);
                        if (r < 0) {
                                log_error_errno(r, "Failed to get parameter: %m");
                                goto fail;
                        }

                        log_info("Received fd=%d", fd);

                        if (write(fd, &x, 1) < 0) {
                                log_error_errno(errno, "Failed to write to fd: %m");
                                safe_close(fd);
                                goto fail;
                        }

                        r = sd_bus_reply_method_return(m, NULL);
                        if (r < 0) {
                                log_error_errno(r, "Failed to send reply: %m");
                                goto fail;
                        }

                } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {

                        r = sd_bus_reply_method_error(
                                        m,
                                        &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
                        if (r < 0) {
                                log_error_errno(r, "Failed to send reply: %m");
                                goto fail;
                        }
                }
        }

        r = 0;

fail:
        if (bus) {
                sd_bus_flush(bus);
                sd_bus_unref(bus);
        }

        return r;
}
예제 #4
0
static void *server(void *p) {
        struct context *c = p;
        sd_bus *bus = NULL;
        sd_id128_t id;
        bool quit = false;
        int r;

        assert_se(sd_id128_randomize(&id) >= 0);

        assert_se(sd_bus_new(&bus) >= 0);
        assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
        assert_se(sd_bus_set_server(bus, 1, id) >= 0);
        assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
        assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
        assert_se(sd_bus_start(bus) >= 0);

        while (!quit) {
                _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;

                r = sd_bus_process(bus, &m);
                if (r < 0) {
                        log_error("Failed to process requests: %s", strerror(-r));
                        goto fail;
                }

                if (r == 0) {
                        r = sd_bus_wait(bus, (uint64_t) -1);
                        if (r < 0) {
                                log_error("Failed to wait: %s", strerror(-r));
                                goto fail;
                        }

                        continue;
                }

                if (!m)
                        continue;

                log_info("Got message! member=%s", strna(sd_bus_message_get_member(m)));

                if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) {

                        assert_se((sd_bus_can_send(bus, 'h') >= 1) == (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));

                        r = sd_bus_message_new_method_return(m, &reply);
                        if (r < 0) {
                                log_error("Failed to allocate return: %s", strerror(-r));
                                goto fail;
                        }

                        quit = true;

                } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
                        r = sd_bus_message_new_method_error(
                                        m,
                                        &reply,
                                        &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
                        if (r < 0) {
                                log_error("Failed to allocate return: %s", strerror(-r));
                                goto fail;
                        }
                }

                if (reply) {
                        r = sd_bus_send(bus, reply, NULL);
                        if (r < 0) {
                                log_error("Failed to send reply: %s", strerror(-r));
                                goto fail;
                        }
                }
        }

        r = 0;

fail:
        if (bus) {
                sd_bus_flush(bus);
                sd_bus_unref(bus);
        }

        return INT_TO_PTR(r);
}
예제 #5
0
/*
 * ----------------------------------------------------------------
 * Router function for any LED operations that come via dbus
 *----------------------------------------------------------------
 */
static int led_function_router(sd_bus_message *msg, void *user_data,
                               sd_bus_error *ret_error)
{
    /* Generic error reporter. */
    int rc = -1;

    /* Extract the led name from the full dbus path */
    const char *led_path = sd_bus_message_get_path(msg);
    if(led_path == NULL)
    {
        fprintf(stderr, "Error. LED path is empty");
        return sd_bus_reply_method_return(msg, "i", rc);
    }

    char *led_name = get_led_name(led_path);
    if(led_name == NULL)
    {
        fprintf(stderr, "Invalid LED name for path :[%s]\n",led_path);
        return sd_bus_reply_method_return(msg, "i", rc);
    }

    /* Now that we have the LED name, get the Operation. */
    const char *led_function = sd_bus_message_get_member(msg);
    if(led_function == NULL)
    {
        fprintf(stderr, "Null LED function specificed for : [%s]\n",led_name);
        return sd_bus_reply_method_return(msg, "i", rc);
    }

    /* Route the user action to appropriate handlers. */
    if( (strcmp(led_function, "setOn") == 0) ||
        (strcmp(led_function, "setOff") == 0))
    {
        rc = led_stable_state_function(led_name, led_function);
        return sd_bus_reply_method_return(msg, "i", rc);
    }
    else if( (strcmp(led_function, "setBlinkFast") == 0) ||
             (strcmp(led_function, "setBlinkSlow") == 0))
    {
        rc = led_default_blink(led_name, led_function);
        return sd_bus_reply_method_return(msg, "i", rc);
    }
    else if(strcmp(led_function, "GetLedState") == 0)
    {
        char value_str[10] = {0};
        const char *led_state = NULL;

        rc = read_led(led_name, power_ctrl, value_str, sizeof(value_str));
        if(rc >= 0)
        {
            /* LED is active low */
            led_state = strtoul(value_str, NULL, 0) ? "Off" : "On";
        }
        return sd_bus_reply_method_return(msg, "is", rc, led_state);
    }
    else
    {
        fprintf(stderr,"Invalid LED function:[%s]\n",led_function);
    }

    return sd_bus_reply_method_return(msg, "i", rc);
}