Skip to content

Commit

Permalink
WIP: Add ping test.
Browse files Browse the repository at this point in the history
Just a preview of the Binder ping test.
  • Loading branch information
wedsonaf committed Jun 8, 2021
1 parent bc06587 commit 76001a4
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 0 deletions.
1 change: 1 addition & 0 deletions tools/testing/selftests/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
TARGETS = arm64
TARGETS += binder
TARGETS += bpf
TARGETS += breakpoints
TARGETS += capabilities
Expand Down
11 changes: 11 additions & 0 deletions tools/testing/selftests/binder/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: GPL-2.0

CFLAGS += -I../../../../usr/include/
CFLAGS += -g
CFLAGS += -D_GNU_SOURCE
CFLAGS += -Wall
CFLAGS += -pthread

TEST_GEN_PROGS := ping_server ping_client

include ../lib.mk
126 changes: 126 additions & 0 deletions tools/testing/selftests/binder/ping_client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdalign.h>
#include <time.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/android/binder.h>

static size_t handle_read(int fd, struct binder_write_read *b)
{
char *ptr = (char *)b->read_buffer;
char *limit = ptr + b->read_consumed;
struct binder_transaction_data *tr;
size_t ret = 0;

while (limit - ptr >= sizeof(uint32_t)) {
uint32_t v = *(uint32_t *)ptr;
ptr += sizeof(uint32_t);
switch (v) {
case BR_REPLY:
tr = (struct binder_transaction_data *)ptr;
ptr += sizeof(*tr);
if (ptr > limit) {
printf("Truncated transaction.\n");
break;
}
ret = tr->data.ptr.buffer;
break;

case BR_NOOP:
break;

case BR_TRANSACTION_COMPLETE:
break;

default:
printf("Unknown reply: 0x%x\n", v);
ptr = limit;
}
}

return ret;
}

int main(int argc, char **argv)
{
int ret;
size_t i;
struct timespec begin, end;

if (argc != 2) {
fprintf(stderr, "Usage: %s <binder-file-name>\n", argv[0]);
return 1;
}

int fd = open(argv[1], O_RDWR);
if (fd == -1) {
perror("open");
return 1;
}

void *shared_ptr = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE, fd, 0);
if (shared_ptr == MAP_FAILED) {
perror("mmap");
return 1;
}

uint32_t buf[512];
static struct __attribute__((__packed__)) {
uint32_t cmd0;
size_t addr;
uint32_t cmd1;
struct binder_transaction_data tr;
} to_write = {
.cmd0 = BC_FREE_BUFFER,
.addr = 0,
.cmd1 = BC_TRANSACTION,
.tr.target.handle = 0,
.tr.code = 0,
};
struct binder_write_read b = {
.write_buffer = (size_t)&to_write,
.write_size = sizeof(to_write),
.read_buffer = (size_t)&buf[0],
.read_size = sizeof(buf),
};
ret = ioctl(fd, BINDER_WRITE_READ, &b);
if (ret == -1) {
perror("ioctl");
return 1;
}

to_write.addr = handle_read(fd, &b);

clock_gettime(CLOCK_MONOTONIC, &begin);
for (i = 0; i < 1000000; i++) {
b.read_consumed = 0;
b.write_consumed = 0;
ret = ioctl(fd, BINDER_WRITE_READ, &b);
if (ret == -1) {
perror("ioctl");
return 1;
}
to_write.addr = handle_read(fd, &b);
}
clock_gettime(CLOCK_MONOTONIC, &end);

end.tv_sec -= begin.tv_sec;
if (begin.tv_nsec > end.tv_nsec) {
end.tv_sec--;
end.tv_nsec += 1000000000;
}
end.tv_nsec -= begin.tv_nsec;
printf("Total time: %lld.%.9ld\n", (long long)end.tv_sec, end.tv_nsec);

close(fd);

return 0;
}
121 changes: 121 additions & 0 deletions tools/testing/selftests/binder/ping_server.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdalign.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/android/binder.h>

static void handle_read(int fd, struct binder_write_read* b)
{
static struct __attribute__((__packed__)) {
uint32_t cmd0;
size_t ptr;
uint32_t cmd1;
struct binder_transaction_data tr;
} to_write = {
.cmd0 = BC_FREE_BUFFER,
.cmd1 = BC_REPLY,
.tr.target.handle = 0,
.tr.code = 0,
};
char *ptr = (char *)b->read_buffer;
char *limit = ptr + b->read_consumed;
struct binder_transaction_data *tr;

while (limit - ptr >= sizeof(uint32_t)) {
uint32_t v = *(uint32_t *)ptr;
ptr += sizeof(uint32_t);
switch (v) {
case BR_TRANSACTION:
tr = (struct binder_transaction_data *)ptr;
ptr += sizeof(*tr);
if (ptr > limit) {
printf("Truncated transaction.\n");
break;
}

to_write.ptr = tr->data.ptr.buffer;
b->write_buffer = (size_t)&to_write;
b->write_size = sizeof(to_write);
b->write_consumed = 0;
break;

case BR_NOOP:
break;

case BR_TRANSACTION_COMPLETE:
break;

default:
printf("Unknown reply: 0x%x\n", v);
ptr = limit;
}
}
}

int main(int argc, char **argv)
{
int ret;

if (argc != 2) {
fprintf(stderr, "Usage: %s <binder-file-name>\n", argv[0]);
return 1;
}

int fd = open(argv[1], O_RDWR);
if (fd == -1) {
perror("open");
return 1;
}

void *shared_ptr = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE, fd, 0);
if (shared_ptr == MAP_FAILED) {
perror("mmap");
return 1;
}

ret = ioctl(fd, BINDER_SET_CONTEXT_MGR, NULL);
if (ret == -1) {
perror("ioctl");
return 1;
}

{
uint32_t cmd = BC_ENTER_LOOPER;
struct binder_write_read b = {
.write_buffer = (size_t)&cmd,
.write_size = sizeof(cmd),
};
int ret = ioctl(fd, BINDER_WRITE_READ, &b);
if (ret == -1) {
perror("ioctl(BC_ENTER_LOOPER)");
}
}

uint32_t buf[512];
struct binder_write_read b = {
.read_buffer = (size_t)&buf[0],
.read_size = sizeof(buf),
};
for (;;) {
b.read_consumed = 0;
ret = ioctl(fd, BINDER_WRITE_READ, &b);
if (ret == -1) {
perror("ioctl");
continue;
}

handle_read(fd, &b);
}

close(fd);

return 0;
}

0 comments on commit 76001a4

Please sign in to comment.