int msg_send(const struct conn *conn,
const char *name,
uint64_t cookie,
+ uint64_t flags,
+ uint64_t timeout,
uint64_t dst_id)
{
struct kdbus_msg *msg;
}
memset(msg, 0, size);
+ msg->flags = flags;
+ msg->timeout_ns = timeout;
msg->size = size;
msg->src_id = conn->id;
msg->dst_id = name ? 0 : dst_id;
(unsigned long long)msg->cookie, (unsigned long long)timeout, (unsigned long long)cookie_reply);
KDBUS_ITEM_FOREACH(item, msg, items) {
- if (item->size <= KDBUS_ITEM_HEADER_SIZE) {
+ if (item->size < KDBUS_ITEM_HEADER_SIZE) {
printf(" +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
break;
}
int msg_recv(struct conn *conn);
void msg_dump(const struct conn *conn, const struct kdbus_msg *msg);
char *msg_id(uint64_t id, char *buf);
-int msg_send(const struct conn *conn, const char *name, uint64_t cookie, uint64_t dst_id);
+int msg_send(const struct conn *conn, const char *name, uint64_t cookie,
+ uint64_t flags, uint64_t timeout, uint64_t dst_id);
struct conn *connect_to_bus(const char *path, uint64_t hello_flags);
void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_item *policy, __u64 max_size);
struct kdbus_item *make_policy_name(const char *name);
add_match_empty(conn_b->fd);
cookie = 0;
- msg_send(conn_b, NULL, 0xc0000000 | cookie, KDBUS_DST_ID_BROADCAST);
+ msg_send(conn_b, NULL, 0xc0000000 | cookie, 0, 0, KDBUS_DST_ID_BROADCAST);
fds[0].fd = conn_a->fd;
fds[1].fd = conn_b->fd;
name_release(conn_a, "foo.bar.baz");
msg_recv(conn_a);
- msg_send(conn_a, NULL, 0xc0000000 | cookie++, conn_b->id);
+ msg_send(conn_a, NULL, 0xc0000000 | cookie++, 0, 0, conn_b->id);
}
if (fds[1].revents & POLLIN) {
msg_recv(conn_b);
- msg_send(conn_b, NULL, 0xc0000000 | cookie++, conn_a->id);
+ msg_send(conn_b, NULL, 0xc0000000 | cookie++, 0, 0, conn_a->id);
}
name_list(conn_b, KDBUS_NAME_LIST_UNIQUE|
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <sys/ioctl.h>
+
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+int main(int argc, char *argv[])
+{
+ struct {
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
+
+ /* name item */
+ uint64_t n_size;
+ uint64_t n_type;
+ char name[64];
+ } bus_make;
+ int fdc, ret, cookie;
+ char *bus;
+ struct conn *conn_a, *conn_b;
+ struct pollfd fds[2];
+
+ printf("-- opening /dev/" KBUILD_MODNAME "/control\n");
+ fdc = open("/dev/" KBUILD_MODNAME "/control", O_RDWR|O_CLOEXEC);
+ if (fdc < 0) {
+ fprintf(stderr, "--- error %d (%m)\n", fdc);
+ return EXIT_FAILURE;
+ }
+
+ memset(&bus_make, 0, sizeof(bus_make));
+ bus_make.head.flags = KDBUS_MAKE_POLICY_OPEN;
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
+
+ snprintf(bus_make.name, sizeof(bus_make.name), "%u-testbus", getuid());
+ bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
+ bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) +
+ sizeof(bus_make.bs) +
+ bus_make.n_size;
+
+ printf("-- creating bus '%s'\n", bus_make.name);
+ ret = ioctl(fdc, KDBUS_CMD_BUS_MAKE, &bus_make);
+ if (ret) {
+ fprintf(stderr, "--- error %d (%m)\n", ret);
+ return EXIT_FAILURE;
+ }
+
+ if (asprintf(&bus, "/dev/" KBUILD_MODNAME "/%s/bus", bus_make.name) < 0)
+ return EXIT_FAILURE;
+
+ conn_a = connect_to_bus(bus, 0);
+ conn_b = connect_to_bus(bus, 0);
+ if (!conn_a || !conn_b)
+ return EXIT_FAILURE;
+
+ cookie = 0;
+ fds[0].fd = conn_a->fd;
+ fds[1].fd = conn_b->fd;
+
+ /* send messages that expects a reply (within 1 sec), but never answer it */
+ msg_send(conn_b, NULL, ++cookie, KDBUS_MSG_FLAGS_EXPECT_REPLY, 4000 * 1000 * 1000ULL, conn_a->id);
+ msg_send(conn_b, NULL, ++cookie, KDBUS_MSG_FLAGS_EXPECT_REPLY, 1000 * 1000 * 1000ULL, conn_a->id);
+ msg_send(conn_b, NULL, ++cookie, KDBUS_MSG_FLAGS_EXPECT_REPLY, 2000 * 1000 * 1000ULL, conn_a->id);
+ msg_send(conn_b, NULL, ++cookie, KDBUS_MSG_FLAGS_EXPECT_REPLY, 3000 * 1000 * 1000ULL, conn_a->id);
+
+ for (;;) {
+ int i, nfds = sizeof(fds) / sizeof(fds[0]);
+
+ for (i = 0; i < nfds; i++) {
+ fds[i].events = POLLIN | POLLPRI | POLLHUP;
+ fds[i].revents = 0;
+ }
+
+ printf("--- entering poll\n");
+ ret = poll(fds, nfds, 5000);
+ if (ret == 0)
+ printf("--- timeout\n");
+ if (ret <= 0)
+ break;
+
+ if (fds[0].revents & POLLIN)
+ msg_recv(conn_a);
+
+ if (fds[1].revents & POLLIN)
+ msg_recv(conn_b);
+ }
+
+ printf("-- closing bus connections\n");
+ close(conn_a->fd);
+ close(conn_b->fd);
+ free(conn_a);
+ free(conn_b);
+
+ printf("-- closing bus master\n");
+ close(fdc);
+ free(bus);
+
+ return EXIT_SUCCESS;
+}